From 9aff95f1eb3d0576fa36b53f8502354d5a977461 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 17 Mar 2021 19:15:32 +0300 Subject: [PATCH 01/49] feat_integrity: added check integrity: functions should be present in steps, their variables should have Endpoints --- .../ProcessorUnits/Tests/IntegrityCheck.hs | 88 ++++++++++ .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 151 +++++++++++++----- 2 files changed, 197 insertions(+), 42 deletions(-) create mode 100644 test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs new file mode 100644 index 000000000..b444af89c --- /dev/null +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -0,0 +1,88 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE QuasiQuotes #-} + +{- | +Module : NITTA.Model.Microarchitecture +Description : Create micro architecture functions +Copyright : (c) Daniil Prohorov, 2019 +License : BSD3 +Maintainer : aleksandr.penskoi@gmail.com +Stability : experimental +-} +module NITTA.Model.ProcessorUnits.Tests.IntegrityCheck ( + checkIntegrity, +) where + +import qualified Data.Set as S +import Data.String.Interpolate +import qualified Data.Text as T +import NITTA.Intermediate.Types +import NITTA.Model.Problems +import NITTA.Model.ProcessorUnits + +checkIntegrity pu fs = + let pr = process pu + vars = map variables fs + pids = checkFunction fs $ steps pr + in concat [checkEndpoints var pr pid | pid <- pids, var <- vars] + +{- | Find requested functions fs in steps of a given process + | if not found then error +-} +checkFunction fs stps = + let nullSteps f = + if not . null $ iterSteps f + then iterSteps f + else + error + [__i| Requested function not found: #{ show fs } + in steps: #{ show stps } + |] + iterSteps f = [pID stp | stp <- stps, compFun f $ pDesc stp] + compFun f (FStep F{fun}) = T.pack (show f) == T.replace (T.pack "\"") T.empty (T.pack $ show fun) + compFun _ _ = False + in concatMap nullSteps fs + +{- | For a given pID finds and returns pIDs of Steps which have Endpoints + | if pids not found then error +-} +checkEndpoints vars pr pid = + let (foundRel, foundPid) = checkRelationsEp pid (steps pr) vars $ relations pr + in if vars == foundRel + then foundPid + else + error + [__i| + Not all variables has related Endpoints, + function with pID=#{pid} should have more endpoints at least: #{S.difference vars foundRel}; + expected: [ #{ show vars } ]; + found: [ #{ show foundRel } ] + pr: [ #{pr} ] + |] + +-- | Goes through process relations and finds pIDs related to given pID +checkRelationsEp pid stps vars rels = + let concEp (epVars, epPid) (epVars2, epPid2) = (S.union epVars epVars2, epPid : epPid2) + in foldr concEp (S.empty, []) $ + [ checkStepsEp vars stps v2 + | (Vertical v1 v2) <- rels + , pid == v1 + ] + +{- | Finds given pid in pDesc of Steps, if it's Source or Target then returns it. + | if not found gave error +-} +checkStepsEp vars stps pid = + let combSteps = [S.intersection vars stp | stp <- map stepInfo stps, not $ null stp] + stepInfo Step{pID, pDesc} + | pID == pid = pDescInfo pDesc + | otherwise = S.empty + pDescInfo descr = case descr of + (EndpointRoleStep (Source s)) -> s + (EndpointRoleStep (Target t)) -> S.fromList [t] + _ -> S.empty + in if not $ null combSteps + then (head combSteps, pid) + else error [i|Endpoint with pid=#{ show pid } not found in Steps: #{ show stps }|] diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index f03ce1304..8fee6ab7c 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -18,75 +18,78 @@ Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} module NITTA.Model.ProcessorUnits.Tests.Utils ( - puCoSim, - naiveSynthesis, - isProcessComplete, - incompleteProcessMsg, + puCoSimTestCase, + nittaCoSimTestCase, + finitePUSynthesisProp, + puCoSimProp, algGen, - initialCycleCntxGen, - processAlgOnEndpointGen, - algSynthesisGen, ) where +import Control.Monad +import Data.Atomics.Counter (incrCounter) import Data.CallStack import Data.Default import Data.List (delete) import qualified Data.Map.Strict as M import Data.Set (elems, empty, fromList, intersection, union) +import qualified Data.String.Utils as S import qualified Data.Text as T +import NITTA.Intermediate.DataFlow import NITTA.Intermediate.Functions () import NITTA.Intermediate.Simulation import NITTA.Intermediate.Types +import NITTA.Model.Networks.Bus import NITTA.Model.Networks.Types import NITTA.Model.Problems hiding (Bind, BreakLoop) import NITTA.Model.ProcessorUnits +import NITTA.Model.ProcessorUnits.Tests.IntegrityCheck import NITTA.Model.TargetSystem () +import NITTA.Model.Tests.Microarchitecture import NITTA.Project import qualified NITTA.Project as P +import NITTA.Synthesis import NITTA.Utils import System.Directory -import System.FilePath.Posix +import System.FilePath.Posix (joinPath) import Test.QuickCheck +import Test.QuickCheck.Monadic +import Test.Tasty (TestTree) +import Test.Tasty.HUnit (assertBool, assertFailure, testCase, (@?)) +import Test.Tasty.QuickCheck (testProperty) -{- |Execute co-simulation test for the specific process unit -with or without "naive synthesis". --} -puCoSim :: +-- *Test cases + +-- |Execute co-simulation test for the specific process unit +puCoSimTestCase :: ( HasCallStack - , PUClasses pu String x Int - , WithFunctions pu (F String x) - , P.Testable pu String x - , DefaultX pu x + , PUClasses (pu String x Int) String x Int + , WithFunctions (pu String x Int) (F String x) + , P.Testable (pu String x Int) String x + , DefaultX (pu String x Int) x ) => String -> - pu -> + pu String x Int -> [(String, x)] -> [F String x] -> - Bool -> - IO (TestbenchReport String x) -puCoSim name u cntxCycle alg needBind = do - pwd <- getCurrentDirectory - let mname = toModuleName name - pTargetProjectPath = "gen" mname - pInProjectNittaPath = "." - prj = - Project - { pName = T.pack mname - , pLibPath = "hdl" - , pTargetProjectPath - , pAbsTargetProjectPath = pwd pTargetProjectPath - , pInProjectNittaPath - , pAbsNittaPath = pwd pInProjectNittaPath pTargetProjectPath - , pUnit = - if needBind - then naiveSynthesis alg u - else u - , pUnitEnv = def - , pTestCntx = simulateAlg 5 (CycleCntx $ M.fromList cntxCycle) [] alg - , pTemplates = ["templates/Icarus"] - } - writeProject prj - runTestbench prj + TestTree +puCoSimTestCase name u cntxCycle alg = + testCase name $ do + wd <- getCurrentDirectory + let mname = toModuleName name + pTargetProjectPath = joinPath [wd, "gen", mname] + prj = + Project + { pName = T.pack mname + , pLibPath = "hdl" + , pTargetProjectPath + , pNittaPath = "." + , pUnit = naiveSynthesis alg u + , pUnitEnv = def + , pTestCntx = simulateAlg 5 (CycleCntx $ M.fromList cntxCycle) [] alg + , pTemplates = ["templates/Icarus"] + } + writeProject prj + (tbStatus <$> runTestbench prj) @? (name <> " in " <> pTargetProjectPath) {- |Bind all functions to processor unit and synthesis process with endpoint decisions. @@ -98,6 +101,40 @@ naiveSynthesis alg u0 = naiveSynthesis' $ foldl (flip bind) u0 alg naiveSynthesis' $ endpointDecision u $ endpointOptionToDecision opt | otherwise = u +-- |Execute co-simulation test for the specific microarchitecture and algorithm +nittaCoSimTestCase :: + ( HasCallStack + , Val x + , Integral x + ) => + String -> + BusNetwork String String x Int -> + [F String x] -> + TestTree +nittaCoSimTestCase n tMicroArch alg = + testCase n $ do + report <- + runTargetSynthesisWithUniqName + def + { tName = S.replace " " "_" n + , tMicroArch + , tDFG = fsToDataFlowGraph alg + } + case report of + Right report' -> assertBool "report with bad status" $ tbStatus report' + Left err -> assertFailure $ "can't get report: " ++ err + +-- *Properties + +-- |Is unit synthesis process complete (by function and variables). +finitePUSynthesisProp name pu0 fsGen = + testProperty name $ do + (pu, fs) <- processAlgOnEndpointGen pu0 fsGen + return $ + isProcessComplete pu fs + && null (endpointOptions pu) + && null (checkIntegrity pu fs) + isProcessComplete pu fs = unionsMap variables fs == processedVars pu incompleteProcessMsg pu fs = @@ -107,6 +144,36 @@ incompleteProcessMsg pu fs = processedVars pu = unionsMap variables $ getEndpoints $ process pu +{- |A computational process of functional (Haskell) and logical (Verilog) +simulation should be identical for any correct algorithm. +-} +puCoSimProp name pu0 fsGen = + testProperty name $ do + (pu, fs) <- processAlgOnEndpointGen pu0 fsGen + pTestCntx <- initialCycleCntxGen fs + return $ + monadicIO $ + run $ do + unless (isProcessComplete pu fs) $ + error $ "process is not complete: " <> incompleteProcessMsg pu fs + i <- incrCounter 1 externalTestCntr + wd <- getCurrentDirectory + let pTargetProjectPath = joinPath [wd, "gen", toModuleName name <> "_" <> show i] + prj = + Project + { pName = T.pack $ toModuleName name + , pLibPath = "hdl" + , pTargetProjectPath + , pNittaPath = "." + , pUnit = pu + , pUnitEnv = def + , pTestCntx + , pTemplates = ["templates/Icarus"] + } + writeProject prj + res <- runTestbench prj + unless (tbStatus res) $ error $ "Fail CoSim in: " <> pTargetProjectPath + algGen fsGen = fmap avoidDupVariables $ listOf1 $ oneof fsGen where avoidDupVariables alg = From 8bb769337fd4b91484947c009d78e4e36a3233f2 Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Fri, 19 Mar 2021 16:39:51 +0300 Subject: [PATCH 02/49] Fix function - endpoint vertical relation in Fram. --- src/NITTA/Model/ProcessorUnits/Fram.hs | 39 ++++++++++++++------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Fram.hs b/src/NITTA/Model/ProcessorUnits/Fram.hs index bf9514ec7..87077e43d 100644 --- a/src/NITTA/Model/ProcessorUnits/Fram.hs +++ b/src/NITTA/Model/ProcessorUnits/Fram.hs @@ -98,7 +98,7 @@ data Cell v x t = Cell data Job v x t = Job { function :: F v x , startAt :: Maybe t - , binds, endpoints :: [ProcessStepID] + , binds :: [ProcessStepID] } deriving (Show, Eq) @@ -107,7 +107,6 @@ defJob f = { function = f , startAt = Nothing , binds = [] - , endpoints = [] } instance WithFunctions (Cell v x t) (F v x) where @@ -302,8 +301,8 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where in fromRemain ++ fromCells -- Constant - endpointDecision fram@Fram{memory} d@EndpointSt{epRole = Source vs, epAt} - | Just (addr, cell@Cell{state = DoConstant vs', job = Just Job{function, binds, endpoints}}) <- + endpointDecision fram@Fram{memory, process_} d@EndpointSt{epRole = Source vs, epAt} + | Just (addr, cell@Cell{state = DoConstant vs', job = Just Job{function, binds}}) <- L.find ( \case (_, Cell{state = DoConstant vs'}) -> (vs' L.\\ S.elems vs) /= vs' @@ -313,11 +312,12 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where let vsRemain = vs' L.\\ S.elems vs ((), process_') = runSchedule fram $ do updateTick (sup epAt + 1) - endpoints' <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr + eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr when (null vsRemain) $ do fPID <- scheduleFunction (0 ... sup epAt) function establishVerticalRelations binds fPID - establishVerticalRelations fPID (endpoints ++ endpoints') + let low = eps ++ map pID (relatedEndpoints process_ $ variables function) + establishVerticalRelations fPID low cell' = case vsRemain of [] -> cell @@ -334,7 +334,7 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where } -- Loop endpointDecision fram@Fram{memory} d@EndpointSt{epRole = Source vs, epAt} - | Just (addr, cell@Cell{state = DoLoopSource vs' oJob, job = Just job@Job{binds, function, startAt, endpoints}}) <- + | Just (addr, cell@Cell{state = DoLoopSource vs' oJob, job = Just job@Job{binds, function, startAt}}) <- L.find ( \case (_, Cell{state = DoLoopSource vs' _}) -> (vs' L.\\ S.elems vs) /= vs' @@ -342,19 +342,20 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where ) $ A.assocs memory = let vsRemain = vs' L.\\ S.elems vs - (endpoints', process_) = runSchedule fram $ do + (_endpoints, process_) = runSchedule fram $ do updateTick (sup epAt + 1) eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr when (null vsRemain) $ do fPID <- scheduleFunction (0 ... sup epAt) function establishVerticalRelations binds fPID - establishVerticalRelations fPID $ eps ++ endpoints + let low = eps ++ map pID (relatedEndpoints process_ $ variables function) + establishVerticalRelations fPID low return eps cell' = if not $ null vsRemain then cell - { job = Just job{startAt = startAt <|> Just (inf epAt - 1), endpoints = endpoints' ++ endpoints} + { job = Just job{startAt = startAt <|> Just (inf epAt - 1)} , state = DoLoopSource vsRemain oJob } else @@ -364,14 +365,15 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where } in fram{process_, memory = memory A.// [(addr, cell')]} endpointDecision fram@Fram{memory} d@EndpointSt{epRole = Target v, epAt} - | Just (addr, cell@Cell{job = Just Job{function, binds, endpoints}}) <- + | Just (addr, cell@Cell{job = Just Job{function, binds}}) <- L.find (\case (_, Cell{state = DoLoopTarget v'}) -> v == v'; _ -> False) $ A.assocs memory = let ((), process_) = runSchedule fram $ do - endpoints' <- scheduleEndpoint d $ scheduleInstruction epAt $ Write addr + eps <- scheduleEndpoint d $ scheduleInstruction epAt $ Write addr updateTick (sup epAt + 1) fPID <- scheduleFunction epAt function establishVerticalRelations binds fPID - establishVerticalRelations fPID (endpoints ++ endpoints') + let low = eps ++ map pID (relatedEndpoints process_ $ variables function) + establishVerticalRelations fPID low cell' = cell { job = Nothing @@ -385,12 +387,12 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where endpointDecision fram@Fram{memory, remainBuffers} d@EndpointSt{epRole = Target v, epAt} | Just (addr, cell@Cell{history}) <- findForBufferCell fram , ([(Buffer (I _) (O vs), j@Job{function})], remainBuffers') <- L.partition (\(Buffer (I v') (O _), _) -> v' == v) remainBuffers = - let (endpoints, process_) = runSchedule fram $ do + let (_endpoints, process_) = runSchedule fram $ do updateTick (sup epAt + 1) scheduleEndpoint d $ scheduleInstruction epAt $ Write addr cell' = cell - { job = Just j{startAt = Just $ inf epAt, endpoints} + { job = Just j{startAt = Just $ inf epAt} , state = DoBuffer $ S.elems vs , lastWrite = Just $ sup epAt , history = function : history @@ -401,7 +403,7 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where , process_ } endpointDecision fram@Fram{memory} d@EndpointSt{epRole = Source vs, epAt} - | Just (addr, cell@Cell{state = DoBuffer vs', job = Just Job{function, startAt = Just fBegin, binds, endpoints}}) <- + | Just (addr, cell@Cell{state = DoBuffer vs', job = Just Job{function, startAt = Just fBegin, binds}}) <- L.find ( \case (_, Cell{state = DoBuffer vs'}) -> (vs' L.\\ S.elems vs) /= vs' @@ -411,11 +413,12 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where let vsRemain = vs' L.\\ S.elems vs ((), process_) = runSchedule fram $ do updateTick (sup epAt + 1) - endpoints' <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr + eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr when (null vsRemain) $ do fPID <- scheduleFunction (fBegin ... sup epAt) function establishVerticalRelations binds fPID - establishVerticalRelations fPID (endpoints ++ endpoints') + let low = eps ++ map pID (relatedEndpoints process_ $ variables function) + establishVerticalRelations fPID low cell' = case vsRemain of [] -> cell From 3355b9555ff5bda4aa7676bab5be6b29276a4704 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Fri, 19 Mar 2021 02:30:34 +0300 Subject: [PATCH 03/49] feat_integrity: written functions to create maps --- .../ProcessorUnits/Tests/IntegrityCheck.hs | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs index b444af89c..67b3bf55d 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -4,9 +4,9 @@ {-# LANGUAGE QuasiQuotes #-} {- | -Module : NITTA.Model.Microarchitecture -Description : Create micro architecture functions -Copyright : (c) Daniil Prohorov, 2019 +Module : NITTA.Model.ProcessorUnits.Tests.IntegrityCheck +Description : Tests vertical relations in PU +Copyright : (c) co0ll3r, 2021 License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental @@ -15,35 +15,58 @@ module NITTA.Model.ProcessorUnits.Tests.IntegrityCheck ( checkIntegrity, ) where +import qualified Data.Map.Strict as M +import Data.Maybe import qualified Data.Set as S import Data.String.Interpolate -import qualified Data.Text as T import NITTA.Intermediate.Types import NITTA.Model.Problems import NITTA.Model.ProcessorUnits checkIntegrity pu fs = let pr = process pu - vars = map variables fs - pids = checkFunction fs $ steps pr - in concat [checkEndpoints var pr pid | pid <- pids, var <- vars] + -- TODO: possible to rewrite without unpacking? + -- TODO check whetehr it null + toIntermidiateMap = foldr findIntermidiate M.empty $ steps pr + toEndpointMap = foldr findEndpoint M.empty $ steps pr + --toInstructionMap = foldr findInstruction M.empty $ steps pr + --- TODO pattern match at params + findIntermidiate step m = case pDesc step of + (FStep fun) -> M.insert (pID step) fun m + _ -> m + findEndpoint step m = case pDesc step of + (EndpointRoleStep (Source s)) -> M.insert (pID step) s m + (EndpointRoleStep (Target t)) -> M.insert (pID step) (S.fromList [t]) m + _ -> m + in {- + findInstruction step m = case pDesc step of + (InstructionStep instr) -> M.insert (pID step) instr m + _ -> m + -} + checkIntermidiateToEndpointRelation pr fs toIntermidiateMap toEndpointMap -{- | Find requested functions fs in steps of a given process - | if not found then error --} -checkFunction fs stps = - let nullSteps f = - if not . null $ iterSteps f - then iterSteps f - else - error - [__i| Requested function not found: #{ show fs } - in steps: #{ show stps } - |] - iterSteps f = [pID stp | stp <- stps, compFun f $ pDesc stp] - compFun f (FStep F{fun}) = T.pack (show f) == T.replace (T.pack "\"") T.empty (T.pack $ show fun) - compFun _ _ = False - in concatMap nullSteps fs +-- in concat [checkEndpoints var pr pid | pid <- pids, var <- vars] + +checkCadToIntermidiate = undefined + +checkIntermidiateToEndpointRelation pr fs ieMap epMap = + let exec = foldr compRel S.empty rels + rels = relations pr + -- TODO is it work??? + vars = foldr (S.intersection . variables) S.empty fs + compRel (Vertical r1 r2) s = + S.union s $ + S.intersection vars $ + compRel' (M.lookup r1 ieMap) $ M.lookup r2 epMap + compRel _ _ = S.empty + compRel' (Just fun) (Just ep) = ep + -- TODO remove? + compRel' (Just fun) Nothing = error "fun to Nothing" + compRel' Nothing (Just ep) = error "Nothing to EP" + compRel' _ _ = S.empty + in exec + +checkEndpointToInstructionRelation epMap isMap = undefined {- | For a given pID finds and returns pIDs of Steps which have Endpoints | if pids not found then error @@ -59,7 +82,7 @@ checkEndpoints vars pr pid = function with pID=#{pid} should have more endpoints at least: #{S.difference vars foundRel}; expected: [ #{ show vars } ]; found: [ #{ show foundRel } ] - pr: [ #{pr} ] + step: [ #{ reverse (steps pr) !! pid } ] |] -- | Goes through process relations and finds pIDs related to given pID From d03f17bb6b4a73094da068675387b81304f14010 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Sat, 20 Mar 2021 16:28:31 +0300 Subject: [PATCH 04/49] feat_integrity: wrote intermidiate to endpoints function with Data.Map --- .../ProcessorUnits/Tests/IntegrityCheck.hs | 107 ++++++------------ .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 2 +- 2 files changed, 34 insertions(+), 75 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs index 67b3bf55d..cba2b89b0 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -16,7 +16,6 @@ module NITTA.Model.ProcessorUnits.Tests.IntegrityCheck ( ) where import qualified Data.Map.Strict as M -import Data.Maybe import qualified Data.Set as S import Data.String.Interpolate import NITTA.Intermediate.Types @@ -25,87 +24,47 @@ import NITTA.Model.ProcessorUnits checkIntegrity pu fs = let pr = process pu + vars = foldr (S.union . variables) S.empty fs -- TODO: possible to rewrite without unpacking? - -- TODO check whetehr it null - toIntermidiateMap = foldr findIntermidiate M.empty $ steps pr - toEndpointMap = foldr findEndpoint M.empty $ steps pr - --toInstructionMap = foldr findInstruction M.empty $ steps pr - --- TODO pattern match at params + toIntermidiateMap = + if M.null getIntermidiateMap + then Nothing + else Just getIntermidiateMap + getIntermidiateMap = foldr findIntermidiate M.empty $ steps pr findIntermidiate step m = case pDesc step of (FStep fun) -> M.insert (pID step) fun m _ -> m + + --- TODO pattern match at params + toEndpointMap = + let check = + if foldr S.union S.empty (M.elems eps) == vars + then Just eps + else Nothing + eps = foldr findEndpoint M.empty $ steps pr + in check findEndpoint step m = case pDesc step of - (EndpointRoleStep (Source s)) -> M.insert (pID step) s m + (EndpointRoleStep (Source t)) -> M.insert (pID step) t m (EndpointRoleStep (Target t)) -> M.insert (pID step) (S.fromList [t]) m _ -> m - in {- - findInstruction step m = case pDesc step of - (InstructionStep instr) -> M.insert (pID step) instr m - _ -> m - -} - checkIntermidiateToEndpointRelation pr fs toIntermidiateMap toEndpointMap - --- in concat [checkEndpoints var pr pid | pid <- pids, var <- vars] + in checkIntermidiateToEndpointRelation pr toIntermidiateMap toEndpointMap -checkCadToIntermidiate = undefined +checkIntermidiateToEndpointRelation _ Nothing _ = error "No function found in steps of PU!" +checkIntermidiateToEndpointRelation _ _ Nothing = error "Not all variables have their Endpoint!" +checkIntermidiateToEndpointRelation pr (Just ieMap) (Just epMap) = + let checkRelation = foldr compRel S.empty $ relations pr + compRel (Vertical r1 r2) = + S.union $ + compRel' r2 (M.lookup r1 ieMap) $ M.lookup r2 epMap + compRel' pid (Just _) (Just _) = S.fromList [pid] + compRel' _ _ _ = S.empty + in if S.size checkRelation == M.size epMap + then checkRelation + else --- TODO pretty print -checkIntermidiateToEndpointRelation pr fs ieMap epMap = - let exec = foldr compRel S.empty rels - rels = relations pr - -- TODO is it work??? - vars = foldr (S.intersection . variables) S.empty fs - compRel (Vertical r1 r2) s = - S.union s $ - S.intersection vars $ - compRel' (M.lookup r1 ieMap) $ M.lookup r2 epMap - compRel _ _ = S.empty - compRel' (Just fun) (Just ep) = ep - -- TODO remove? - compRel' (Just fun) Nothing = error "fun to Nothing" - compRel' Nothing (Just ep) = error "Nothing to EP" - compRel' _ _ = S.empty - in exec - -checkEndpointToInstructionRelation epMap isMap = undefined - -{- | For a given pID finds and returns pIDs of Steps which have Endpoints - | if pids not found then error --} -checkEndpoints vars pr pid = - let (foundRel, foundPid) = checkRelationsEp pid (steps pr) vars $ relations pr - in if vars == foundRel - then foundPid - else error - [__i| - Not all variables has related Endpoints, - function with pID=#{pid} should have more endpoints at least: #{S.difference vars foundRel}; - expected: [ #{ show vars } ]; - found: [ #{ show foundRel } ] - step: [ #{ reverse (steps pr) !! pid } ] - |] + [i| Steps #{ M.withoutKeys epMap checkRelation } + not related to any FStep!|] --- | Goes through process relations and finds pIDs related to given pID -checkRelationsEp pid stps vars rels = - let concEp (epVars, epPid) (epVars2, epPid2) = (S.union epVars epVars2, epPid : epPid2) - in foldr concEp (S.empty, []) $ - [ checkStepsEp vars stps v2 - | (Vertical v1 v2) <- rels - , pid == v1 - ] - -{- | Finds given pid in pDesc of Steps, if it's Source or Target then returns it. - | if not found gave error --} -checkStepsEp vars stps pid = - let combSteps = [S.intersection vars stp | stp <- map stepInfo stps, not $ null stp] - stepInfo Step{pID, pDesc} - | pID == pid = pDescInfo pDesc - | otherwise = S.empty - pDescInfo descr = case descr of - (EndpointRoleStep (Source s)) -> s - (EndpointRoleStep (Target t)) -> S.fromList [t] - _ -> S.empty - in if not $ null combSteps - then (head combSteps, pid) - else error [i|Endpoint with pid=#{ show pid } not found in Steps: #{ show stps }|] +-- | Print +checkEndpointToInstructionRelation epMap isMap = undefined \ No newline at end of file diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index 8fee6ab7c..d29b10ae8 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -133,7 +133,7 @@ finitePUSynthesisProp name pu0 fsGen = return $ isProcessComplete pu fs && null (endpointOptions pu) - && null (checkIntegrity pu fs) + && not (null $ checkIntegrity pu fs) isProcessComplete pu fs = unionsMap variables fs == processedVars pu From 821d61278dcfb06685cc417f2dad845eaaac6f2d Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Sat, 20 Mar 2021 17:42:19 +0300 Subject: [PATCH 05/49] feat_integrity: added endpoint to instruction check --- .../ProcessorUnits/Tests/IntegrityCheck.hs | 61 +++++++++++++------ .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 2 +- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs index cba2b89b0..5d726c8ac 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -25,34 +25,44 @@ import NITTA.Model.ProcessorUnits checkIntegrity pu fs = let pr = process pu vars = foldr (S.union . variables) S.empty fs - -- TODO: possible to rewrite without unpacking? + toIntermidiateMap = - if M.null getIntermidiateMap - then Nothing - else Just getIntermidiateMap - getIntermidiateMap = foldr findIntermidiate M.empty $ steps pr + let getInterMap = foldr findIntermidiate M.empty $ steps pr + in if M.null getInterMap + then Nothing + else Just getInterMap findIntermidiate step m = case pDesc step of (FStep fun) -> M.insert (pID step) fun m _ -> m - --- TODO pattern match at params toEndpointMap = - let check = - if foldr S.union S.empty (M.elems eps) == vars - then Just eps - else Nothing - eps = foldr findEndpoint M.empty $ steps pr - in check + let getEpMap = foldr findEndpoint M.empty $ steps pr + in if foldr S.union S.empty (M.elems getEpMap) == vars + then Just getEpMap + else Nothing findEndpoint step m = case pDesc step of (EndpointRoleStep (Source t)) -> M.insert (pID step) t m (EndpointRoleStep (Target t)) -> M.insert (pID step) (S.fromList [t]) m _ -> m - in checkIntermidiateToEndpointRelation pr toIntermidiateMap toEndpointMap + + toInstructionMap = + let getInstrMap = foldr findInstruction M.empty $ steps pr + in if M.null getInstrMap + then Nothing + else Just getInstrMap + findInstruction step m = case pDesc step of + instr@(InstructionStep _) -> M.insert (pID step) instr m + _ -> m + in not $ + null $ + checkEndpointToInstructionRelation pr toEndpointMap toInstructionMap $ + checkIntermidiateToEndpointRelation pr toIntermidiateMap toEndpointMap checkIntermidiateToEndpointRelation _ Nothing _ = error "No function found in steps of PU!" checkIntermidiateToEndpointRelation _ _ Nothing = error "Not all variables have their Endpoint!" checkIntermidiateToEndpointRelation pr (Just ieMap) (Just epMap) = let checkRelation = foldr compRel S.empty $ relations pr + compRel (Vertical r1 r2) = S.union $ compRel' r2 (M.lookup r1 ieMap) $ M.lookup r2 epMap @@ -60,11 +70,24 @@ checkIntermidiateToEndpointRelation pr (Just ieMap) (Just epMap) = compRel' _ _ _ = S.empty in if S.size checkRelation == M.size epMap then checkRelation - else --- TODO pretty print + else printError epMap checkRelation - error - [i| Steps #{ M.withoutKeys epMap checkRelation } - not related to any FStep!|] +-- TODO is it possible to combine with checkIntermidiateToEndpointRelation? +checkEndpointToInstructionRelation _ Nothing _ _ = error "Not all variables have their Endpoint!" +checkEndpointToInstructionRelation _ _ Nothing _ = error "Instruction steps not found!" +checkEndpointToInstructionRelation pr (Just epMap) (Just isMap) epPids = + let checkRelation = foldr compRel S.empty $ relations pr --- | Print -checkEndpointToInstructionRelation epMap isMap = undefined \ No newline at end of file + compRel (Vertical r1 r2) = + S.union $ + compRel' r2 (M.lookup r1 epMap) $ M.lookup r2 isMap + compRel' pid (Just _) (Just _) = S.fromList [pid] + compRel' _ _ _ = S.empty + in if S.size checkRelation == S.size epPids + then checkRelation + else printError epMap checkRelation + +printError epMap foundPids = + error --- TODO pretty print + [i| Steps #{ M.withoutKeys epMap foundPids } + not related to any FStep!|] diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index d29b10ae8..d5415f901 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -133,7 +133,7 @@ finitePUSynthesisProp name pu0 fsGen = return $ isProcessComplete pu fs && null (endpointOptions pu) - && not (null $ checkIntegrity pu fs) + && checkIntegrity pu fs isProcessComplete pu fs = unionsMap variables fs == processedVars pu From 11d499e912527921902cac21583354383d64fb07 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Sat, 20 Mar 2021 21:48:07 +0300 Subject: [PATCH 06/49] feat_integrity: check to one more test --- test/NITTA/Model/ProcessorUnits/Tests/Utils.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index d5415f901..df350df94 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -34,6 +34,7 @@ import qualified Data.Map.Strict as M import Data.Set (elems, empty, fromList, intersection, union) import qualified Data.String.Utils as S import qualified Data.Text as T +import qualified Debug.Trace as DebugTrace import NITTA.Intermediate.DataFlow import NITTA.Intermediate.Functions () import NITTA.Intermediate.Simulation @@ -121,7 +122,7 @@ nittaCoSimTestCase n tMicroArch alg = , tDFG = fsToDataFlowGraph alg } case report of - Right report' -> assertBool "report with bad status" $ tbStatus report' + Right report' -> assertBool "report with bad status" $ tbStatus $ DebugTrace.traceShow report' report' Left err -> assertFailure $ "can't get report: " ++ err -- *Properties @@ -154,7 +155,7 @@ puCoSimProp name pu0 fsGen = return $ monadicIO $ run $ do - unless (isProcessComplete pu fs) $ + unless (isProcessComplete pu fs && checkIntegrity pu fs) $ error $ "process is not complete: " <> incompleteProcessMsg pu fs i <- incrCounter 1 externalTestCntr wd <- getCurrentDirectory From d2d696044e84e828288e5fc5b75e041a204d1eef Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Tue, 23 Mar 2021 02:19:41 +0300 Subject: [PATCH 07/49] refactor_integrity: changed to variables function --- test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs index 5d726c8ac..2b2d89061 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -19,7 +19,6 @@ import qualified Data.Map.Strict as M import qualified Data.Set as S import Data.String.Interpolate import NITTA.Intermediate.Types -import NITTA.Model.Problems import NITTA.Model.ProcessorUnits checkIntegrity pu fs = @@ -41,8 +40,7 @@ checkIntegrity pu fs = then Just getEpMap else Nothing findEndpoint step m = case pDesc step of - (EndpointRoleStep (Source t)) -> M.insert (pID step) t m - (EndpointRoleStep (Target t)) -> M.insert (pID step) (S.fromList [t]) m + (EndpointRoleStep t) -> M.insert (pID step) (variables t) m _ -> m toInstructionMap = From 3f7e4e9f6020466902092e80b52799e65d94e020 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Thu, 25 Mar 2021 03:21:15 +0300 Subject: [PATCH 08/49] feat_integrity: rewritten check integrity method (not working) --- .../ProcessorUnits/Tests/IntegrityCheck.hs | 88 +++++-------------- .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 2 +- 2 files changed, 21 insertions(+), 69 deletions(-) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs index 2b2d89061..683ce76f0 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs @@ -1,7 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PartialTypeSignatures #-} -{-# LANGUAGE QuasiQuotes #-} {- | Module : NITTA.Model.ProcessorUnits.Tests.IntegrityCheck @@ -17,75 +15,29 @@ module NITTA.Model.ProcessorUnits.Tests.IntegrityCheck ( import qualified Data.Map.Strict as M import qualified Data.Set as S -import Data.String.Interpolate import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits checkIntegrity pu fs = let pr = process pu - vars = foldr (S.union . variables) S.empty fs - toIntermidiateMap = - let getInterMap = foldr findIntermidiate M.empty $ steps pr - in if M.null getInterMap - then Nothing - else Just getInterMap - findIntermidiate step m = case pDesc step of - (FStep fun) -> M.insert (pID step) fun m - _ -> m - - toEndpointMap = - let getEpMap = foldr findEndpoint M.empty $ steps pr - in if foldr S.union S.empty (M.elems getEpMap) == vars - then Just getEpMap - else Nothing - findEndpoint step m = case pDesc step of - (EndpointRoleStep t) -> M.insert (pID step) (variables t) m - _ -> m - - toInstructionMap = - let getInstrMap = foldr findInstruction M.empty $ steps pr - in if M.null getInstrMap - then Nothing - else Just getInstrMap - findInstruction step m = case pDesc step of - instr@(InstructionStep _) -> M.insert (pID step) instr m - _ -> m - in not $ - null $ - checkEndpointToInstructionRelation pr toEndpointMap toInstructionMap $ - checkIntermidiateToEndpointRelation pr toIntermidiateMap toEndpointMap - -checkIntermidiateToEndpointRelation _ Nothing _ = error "No function found in steps of PU!" -checkIntermidiateToEndpointRelation _ _ Nothing = error "Not all variables have their Endpoint!" -checkIntermidiateToEndpointRelation pr (Just ieMap) (Just epMap) = - let checkRelation = foldr compRel S.empty $ relations pr - - compRel (Vertical r1 r2) = - S.union $ - compRel' r2 (M.lookup r1 ieMap) $ M.lookup r2 epMap - compRel' pid (Just _) (Just _) = S.fromList [pid] - compRel' _ _ _ = S.empty - in if S.size checkRelation == M.size epMap - then checkRelation - else printError epMap checkRelation - --- TODO is it possible to combine with checkIntermidiateToEndpointRelation? -checkEndpointToInstructionRelation _ Nothing _ _ = error "Not all variables have their Endpoint!" -checkEndpointToInstructionRelation _ _ Nothing _ = error "Instruction steps not found!" -checkEndpointToInstructionRelation pr (Just epMap) (Just isMap) epPids = - let checkRelation = foldr compRel S.empty $ relations pr - - compRel (Vertical r1 r2) = - S.union $ - compRel' r2 (M.lookup r1 epMap) $ M.lookup r2 isMap - compRel' pid (Just _) (Just _) = S.fromList [pid] - compRel' _ _ _ = S.empty - in if S.size checkRelation == S.size epPids - then checkRelation - else printError epMap checkRelation - -printError epMap foundPids = - error --- TODO pretty print - [i| Steps #{ M.withoutKeys epMap foundPids } - not related to any FStep!|] + getFuncMap = foldr M.union M.empty filterFunc + filterFunc = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc $ steps pr, pid <- map pID $ steps pr] + + getEpMap = foldr M.union M.empty filterEp + filterEp = [M.insert pid (pid, variables e) M.empty | (EndpointRoleStep e) <- map pDesc $ steps pr, pid <- map pID $ steps pr] + in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pu] + +checkIntermidiateToEndpointRelation fs eps pu = S.isSubsetOf makeRelationList fromRelation + where + fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pu + makeRelationList = + S.fromList $ + concatMap + ( \(h, f) -> + concatMap + ( \v -> [(h, fst (eps M.! v))] + ) + $ variables f + ) + $ M.elems fs \ No newline at end of file diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index df350df94..76fc9402d 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -122,7 +122,7 @@ nittaCoSimTestCase n tMicroArch alg = , tDFG = fsToDataFlowGraph alg } case report of - Right report' -> assertBool "report with bad status" $ tbStatus $ DebugTrace.traceShow report' report' + Right report' -> assertBool "report with bad status" $ tbStatus $ report' Left err -> assertFailure $ "can't get report: " ++ err -- *Properties From 25cbbe709fcef92b601d0b8aa6efe7dd3f5d9e75 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 01:44:18 +0300 Subject: [PATCH 09/49] feat_integrity: added IntegrityCheck file in src --- src/NITTA/Model/IntegrityCheck.hs | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/NITTA/Model/IntegrityCheck.hs diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs new file mode 100644 index 000000000..561f8f67e --- /dev/null +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE PartialTypeSignatures #-} + +{- | +Module : NITTA.Model.ProcessorUnits.Tests.IntegrityCheck +Description : Tests vertical relations in PU +Copyright : (c) co0ll3r, 2021 +License : BSD3 +Maintainer : aleksandr.penskoi@gmail.com +Stability : experimental +-} +module NITTA.Model.IntegrityCheck where + +import qualified Data.Map.Strict as M +import qualified Data.Set as S +import qualified Debug.Trace +import NITTA.Intermediate.Types +import NITTA.Model.ProcessorUnits + +--checkIntegrity :: ProcessorUnit (Process t1 i) ProcessStepID x t2 => Process t1 i -> p -> Bool +--checkIntegrity :: (ProcessorUnit u v x t, Suffix ProcessStepID) => u -> p -> Bool +checkIntegrity pu fs = + let pr = process $ Debug.Trace.traceShow pu pu + getFuncMap = foldr M.union M.empty filterFunc + filterFunc = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc filterFunc', pid <- map pID filterFunc'] + filterFunc' = filter (\stp -> case pDesc stp of FStep _ -> True; _ -> False) $ steps pr + + getEpMap = foldr M.union M.empty filterEp + filterEp = [M.insert pid (pid, variables e) M.empty | (EndpointRoleStep e) <- map pDesc filterEp', pid <- map pID filterEp'] + filterEp' = filter (\stp -> case pDesc stp of EndpointRoleStep _ -> True; _ -> False) $ steps pr + in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pr] + +toIntermidiateMap pu = + let getInterMap = foldr findIntermidiate M.empty $ steps pr + pr = process pu + in if M.null getInterMap + then Nothing + else Just getInterMap +findIntermidiate step m = case pDesc step of + (FStep fun) -> M.insert (pID step) fun m + _ -> m + +getFuncMap pu = foldr M.union M.empty $ filterFunc $ process pu +filterFunc pr = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc $ filterFunc' pr, pid <- map pID $ filterFunc' pr] +filterFunc' pr = filter (\stp -> case pDesc stp of FStep _ -> True; _ -> False) $ steps pr + +getEpMap pu = foldr M.union M.empty $ filterEp $ process pu +filterEp pr = [M.insert pid (pid, variables e) M.empty | step <- filterEp' pr, let e = getEp $ pDesc step, let pid = pID step] +filterEp' pr = filter (\stp -> case pDesc stp of EndpointRoleStep _ -> True; _ -> False) $ steps pr + +getEp (EndpointRoleStep e) = e +getEp _ = error "" + +-- checkIntermidiateToEndpointRelation :: (Ord k1, Variables a k1) => M.Map k2 (ProcessStepID, a) -> M.Map k1 (ProcessStepID, b) -> Process t i -> Bool + +checkIntermidiateToEndpointRelation fs eps pu = S.isSubsetOf makeRelationList fromRelation + where + fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pu + makeRelationList = + S.fromList $ + concatMap + ( \(h, f) -> + concatMap + ( \v -> [(h, fst (eps M.! v))] + ) + $ variables f + ) + $ M.elems fs \ No newline at end of file From 808c0def895173e3bd4f62bcc83f563220afde2d Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 03:52:05 +0300 Subject: [PATCH 10/49] feat_integrity: fixed endpoint map generation --- src/NITTA/Model/IntegrityCheck.hs | 67 +++++++++++++------------------ 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 561f8f67e..ba615bd79 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PartialTypeSignatures #-} {- | @@ -9,53 +10,43 @@ License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} -module NITTA.Model.IntegrityCheck where +module NITTA.Model.IntegrityCheck ( + checkIntegrity, +) where import qualified Data.Map.Strict as M import qualified Data.Set as S -import qualified Debug.Trace import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits +import NITTA.Utils ---checkIntegrity :: ProcessorUnit (Process t1 i) ProcessStepID x t2 => Process t1 i -> p -> Bool ---checkIntegrity :: (ProcessorUnit u v x t, Suffix ProcessStepID) => u -> p -> Bool checkIntegrity pu fs = - let pr = process $ Debug.Trace.traceShow pu pu - getFuncMap = foldr M.union M.empty filterFunc - filterFunc = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc filterFunc', pid <- map pID filterFunc'] - filterFunc' = filter (\stp -> case pDesc stp of FStep _ -> True; _ -> False) $ steps pr - - getEpMap = foldr M.union M.empty filterEp - filterEp = [M.insert pid (pid, variables e) M.empty | (EndpointRoleStep e) <- map pDesc filterEp', pid <- map pID filterEp'] - filterEp' = filter (\stp -> case pDesc stp of EndpointRoleStep _ -> True; _ -> False) $ steps pr + let pr = process pu + getFuncMap = + M.fromList $ + [ (pID, (pID, f)) + | step@Step{pID, pDesc} <- steps pr + , isFB step + , f <- case pDesc of + (FStep f) -> [f] + _ -> [] + ] + --- TODO what if we have 2 same variables? + getEpMap = + M.fromList $ + concat + [ concatMap (\v -> [(v, (pID, ep))]) $ variables ep + | step@Step{pID, pDesc} <- steps pr + , isEndpoint step + , ep <- case pDesc of + (EndpointRoleStep e) -> [e] + _ -> [] + ] in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pr] -toIntermidiateMap pu = - let getInterMap = foldr findIntermidiate M.empty $ steps pr - pr = process pu - in if M.null getInterMap - then Nothing - else Just getInterMap -findIntermidiate step m = case pDesc step of - (FStep fun) -> M.insert (pID step) fun m - _ -> m - -getFuncMap pu = foldr M.union M.empty $ filterFunc $ process pu -filterFunc pr = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc $ filterFunc' pr, pid <- map pID $ filterFunc' pr] -filterFunc' pr = filter (\stp -> case pDesc stp of FStep _ -> True; _ -> False) $ steps pr - -getEpMap pu = foldr M.union M.empty $ filterEp $ process pu -filterEp pr = [M.insert pid (pid, variables e) M.empty | step <- filterEp' pr, let e = getEp $ pDesc step, let pid = pID step] -filterEp' pr = filter (\stp -> case pDesc stp of EndpointRoleStep _ -> True; _ -> False) $ steps pr - -getEp (EndpointRoleStep e) = e -getEp _ = error "" - --- checkIntermidiateToEndpointRelation :: (Ord k1, Variables a k1) => M.Map k2 (ProcessStepID, a) -> M.Map k1 (ProcessStepID, b) -> Process t i -> Bool - -checkIntermidiateToEndpointRelation fs eps pu = S.isSubsetOf makeRelationList fromRelation +checkIntermidiateToEndpointRelation fs eps pr = S.isSubsetOf makeRelationList fromRelation where - fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pu + fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr makeRelationList = S.fromList $ concatMap @@ -65,4 +56,4 @@ checkIntermidiateToEndpointRelation fs eps pu = S.isSubsetOf makeRelationList fr ) $ variables f ) - $ M.elems fs \ No newline at end of file + $ M.elems fs From 6e3c713fbe6965feb43876bf044d9fd64344f461 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 04:01:35 +0300 Subject: [PATCH 11/49] feat_integrity: added isEndpoint method to Utils --- src/NITTA/Utils.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/NITTA/Utils.hs b/src/NITTA/Utils.hs index ff766bd5a..648ac906c 100644 --- a/src/NITTA/Utils.hs +++ b/src/NITTA/Utils.hs @@ -36,6 +36,7 @@ module NITTA.Utils ( relatedEndpoints, isFB, getFBs, + isEndpoint, isInstruction, module NITTA.Utils.Base, ) where @@ -113,6 +114,8 @@ getFB _ = Nothing getFBs p = mapMaybe getFB $ sortOn stepStart $ steps p +isEndpoint ep = isJust $ getEndpoint ep + getEndpoint Step{pDesc} | EndpointRoleStep role <- descent pDesc = Just role getEndpoint _ = Nothing From ade37fa35076c126ece9582e3b442c012d3dcce0 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 04:29:31 +0300 Subject: [PATCH 12/49] feat_integrity: change using to internal integrity test, cleaning in IntegrityCheck --- src/NITTA/Model/IntegrityCheck.hs | 13 ++++-- src/NITTA/Synthesis/Explore.hs | 1 + .../ProcessorUnits/Tests/IntegrityCheck.hs | 43 ------------------- .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 7 ++- 4 files changed, 14 insertions(+), 50 deletions(-) delete mode 100644 test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index ba615bd79..53fd7a91f 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -3,15 +3,16 @@ {-# LANGUAGE PartialTypeSignatures #-} {- | -Module : NITTA.Model.ProcessorUnits.Tests.IntegrityCheck +Module : NITTA.Model.IntegrityCheck Description : Tests vertical relations in PU -Copyright : (c) co0ll3r, 2021 +Copyright : (c) Artyom Kostyuchik, 2021 License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} module NITTA.Model.IntegrityCheck ( checkIntegrity, + checkIntegrityInternal, ) where import qualified Data.Map.Strict as M @@ -21,6 +22,10 @@ import NITTA.Model.ProcessorUnits import NITTA.Utils checkIntegrity pu fs = + checkFunctionToIntermidiateRelation pu fs + && checkIntegrityInternal pu + +checkIntegrityInternal pu = let pr = process pu getFuncMap = M.fromList $ @@ -31,7 +36,7 @@ checkIntegrity pu fs = (FStep f) -> [f] _ -> [] ] - --- TODO what if we have 2 same variables? + --- TODO what if we have 2 same variables? Link will be only to 1 getEpMap = M.fromList $ concat @@ -57,3 +62,5 @@ checkIntermidiateToEndpointRelation fs eps pr = S.isSubsetOf makeRelationList fr $ variables f ) $ M.elems fs +checkFunctionToIntermidiateRelation pu fs = True +checkEndpointToInstructionRelation = undefined \ No newline at end of file diff --git a/src/NITTA/Synthesis/Explore.hs b/src/NITTA/Synthesis/Explore.hs index a12de78ec..31e0d55c9 100644 --- a/src/NITTA/Synthesis/Explore.hs +++ b/src/NITTA/Synthesis/Explore.hs @@ -31,6 +31,7 @@ import qualified Data.List as L import qualified Data.Map.Strict as M import qualified Data.Set as S import NITTA.Intermediate.Types +import NITTA.Model.IntegrityCheck import NITTA.Model.Networks.Bus import NITTA.Model.Problems.Bind import NITTA.Model.Problems.Dataflow diff --git a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs b/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs deleted file mode 100644 index 683ce76f0..000000000 --- a/test/NITTA/Model/ProcessorUnits/Tests/IntegrityCheck.hs +++ /dev/null @@ -1,43 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE PartialTypeSignatures #-} - -{- | -Module : NITTA.Model.ProcessorUnits.Tests.IntegrityCheck -Description : Tests vertical relations in PU -Copyright : (c) co0ll3r, 2021 -License : BSD3 -Maintainer : aleksandr.penskoi@gmail.com -Stability : experimental --} -module NITTA.Model.ProcessorUnits.Tests.IntegrityCheck ( - checkIntegrity, -) where - -import qualified Data.Map.Strict as M -import qualified Data.Set as S -import NITTA.Intermediate.Types -import NITTA.Model.ProcessorUnits - -checkIntegrity pu fs = - let pr = process pu - - getFuncMap = foldr M.union M.empty filterFunc - filterFunc = [M.insert pid (pid, f) M.empty | (FStep f) <- map pDesc $ steps pr, pid <- map pID $ steps pr] - - getEpMap = foldr M.union M.empty filterEp - filterEp = [M.insert pid (pid, variables e) M.empty | (EndpointRoleStep e) <- map pDesc $ steps pr, pid <- map pID $ steps pr] - in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pu] - -checkIntermidiateToEndpointRelation fs eps pu = S.isSubsetOf makeRelationList fromRelation - where - fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pu - makeRelationList = - S.fromList $ - concatMap - ( \(h, f) -> - concatMap - ( \v -> [(h, fst (eps M.! v))] - ) - $ variables f - ) - $ M.elems fs \ No newline at end of file diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index 76fc9402d..f4b6d0de4 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -34,16 +34,15 @@ import qualified Data.Map.Strict as M import Data.Set (elems, empty, fromList, intersection, union) import qualified Data.String.Utils as S import qualified Data.Text as T -import qualified Debug.Trace as DebugTrace import NITTA.Intermediate.DataFlow import NITTA.Intermediate.Functions () import NITTA.Intermediate.Simulation import NITTA.Intermediate.Types +import NITTA.Model.IntegrityCheck import NITTA.Model.Networks.Bus import NITTA.Model.Networks.Types import NITTA.Model.Problems hiding (Bind, BreakLoop) import NITTA.Model.ProcessorUnits -import NITTA.Model.ProcessorUnits.Tests.IntegrityCheck import NITTA.Model.TargetSystem () import NITTA.Model.Tests.Microarchitecture import NITTA.Project @@ -134,7 +133,7 @@ finitePUSynthesisProp name pu0 fsGen = return $ isProcessComplete pu fs && null (endpointOptions pu) - && checkIntegrity pu fs + && checkIntegrityInternal pu isProcessComplete pu fs = unionsMap variables fs == processedVars pu @@ -155,7 +154,7 @@ puCoSimProp name pu0 fsGen = return $ monadicIO $ run $ do - unless (isProcessComplete pu fs && checkIntegrity pu fs) $ + unless (isProcessComplete pu fs && checkIntegrityInternal pu) $ error $ "process is not complete: " <> incompleteProcessMsg pu fs i <- incrCounter 1 externalTestCntr wd <- getCurrentDirectory From 5973f5003423da879fbfd0aa7153f15da4594ae1 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 04:51:12 +0300 Subject: [PATCH 13/49] feat_integrity: added function to intermediate relation check --- src/NITTA/Model/IntegrityCheck.hs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 53fd7a91f..7f29a272a 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -49,7 +49,13 @@ checkIntegrityInternal pu = ] in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pr] -checkIntermidiateToEndpointRelation fs eps pr = S.isSubsetOf makeRelationList fromRelation +checkFunctionToIntermidiateRelation pu fs = + let fsVars = unionsMap variables fs + puFuncVars = unionsMap variables $ getFBs (process pu) + in fsVars == transferred pu + && fsVars == puFuncVars + +checkIntermidiateToEndpointRelation ifs eps pr = S.isSubsetOf makeRelationList fromRelation where fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr makeRelationList = @@ -61,6 +67,4 @@ checkIntermidiateToEndpointRelation fs eps pr = S.isSubsetOf makeRelationList fr ) $ variables f ) - $ M.elems fs -checkFunctionToIntermidiateRelation pu fs = True -checkEndpointToInstructionRelation = undefined \ No newline at end of file + $ M.elems ifs \ No newline at end of file From 61a43769dff5e62d7a1c75509a093221ecca0557 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 06:24:17 +0300 Subject: [PATCH 14/49] feat_integrity: added check endpoints to instructions --- src/NITTA/Model/IntegrityCheck.hs | 30 ++++++++++++++----- .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 2 +- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 7f29a272a..c00c82153 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -10,10 +10,7 @@ License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} -module NITTA.Model.IntegrityCheck ( - checkIntegrity, - checkIntegrityInternal, -) where +module NITTA.Model.IntegrityCheck where import qualified Data.Map.Strict as M import qualified Data.Set as S @@ -36,7 +33,7 @@ checkIntegrityInternal pu = (FStep f) -> [f] _ -> [] ] - --- TODO what if we have 2 same variables? Link will be only to 1 + --- TODO what if we have 2 same variables? The key will be only one getEpMap = M.fromList $ concat @@ -47,7 +44,17 @@ checkIntegrityInternal pu = (EndpointRoleStep e) -> [e] _ -> [] ] - in and [checkIntermidiateToEndpointRelation getFuncMap getEpMap pr] + -- TODO why instruction could be the same in case with two binded functions? + getInstrMap = + M.fromList $ + [ (pID, (pID, pDesc)) + | Step{pID, pDesc} <- steps pr + , isInstruction pDesc + ] + in and + [ checkIntermidiateToEndpointRelation getFuncMap getEpMap pr + , checkEndpointToInstructionRelation getFuncMap getInstrMap pr + ] checkFunctionToIntermidiateRelation pu fs = let fsVars = unionsMap variables fs @@ -67,4 +74,13 @@ checkIntermidiateToEndpointRelation ifs eps pr = S.isSubsetOf makeRelationList f ) $ variables f ) - $ M.elems ifs \ No newline at end of file + $ M.elems ifs + +checkEndpointToInstructionRelation eps ins pr = + let eps_ = M.fromList $ M.elems eps + ins_ = M.fromList $ M.elems ins + fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr + checkRel (v1, v2) = case eps_ M.!? v1 of + Just _ | Just (InstructionStep _) <- ins_ M.!? v2 -> [True] + _ -> [] + in and $ concatMap checkRel fromRelation \ No newline at end of file diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index f4b6d0de4..b6b02e915 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -121,7 +121,7 @@ nittaCoSimTestCase n tMicroArch alg = , tDFG = fsToDataFlowGraph alg } case report of - Right report' -> assertBool "report with bad status" $ tbStatus $ report' + Right report' -> assertBool "report with bad status" $ tbStatus report' Left err -> assertFailure $ "can't get report: " ++ err -- *Properties From 7cfb6cc6349379cc489ded78b8fa5bd2b1d32bf5 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Wed, 31 Mar 2021 21:42:03 +0300 Subject: [PATCH 15/49] fix_integrity: added IntegrityCheck to cabal --- nitta.cabal | 1 + 1 file changed, 1 insertion(+) diff --git a/nitta.cabal b/nitta.cabal index 84a7d6049..0c50e52b5 100644 --- a/nitta.cabal +++ b/nitta.cabal @@ -58,6 +58,7 @@ library NITTA.Intermediate.Value NITTA.Intermediate.Variable NITTA.LuaFrontend + NITTA.Model.IntegrityCheck NITTA.Model.Microarchitecture NITTA.Model.Networks.Bus NITTA.Model.Networks.Types From af9bf2414acfca01527e70b0c9ca76d050c88cc3 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Thu, 1 Apr 2021 02:20:39 +0300 Subject: [PATCH 16/49] refactor_integrity: renamed functions --- src/NITTA/Model/IntegrityCheck.hs | 28 +++++++++---------- .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 4 +-- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index c00c82153..760967bbd 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -10,7 +10,9 @@ License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} -module NITTA.Model.IntegrityCheck where +module NITTA.Model.IntegrityCheck ( + checkIntegrity, +) where import qualified Data.Map.Strict as M import qualified Data.Set as S @@ -18,13 +20,9 @@ import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits import NITTA.Utils -checkIntegrity pu fs = - checkFunctionToIntermidiateRelation pu fs - && checkIntegrityInternal pu - -checkIntegrityInternal pu = +checkIntegrity pu = let pr = process pu - getFuncMap = + getInterMap = M.fromList $ [ (pID, (pID, f)) | step@Step{pID, pDesc} <- steps pr @@ -44,27 +42,27 @@ checkIntegrityInternal pu = (EndpointRoleStep e) -> [e] _ -> [] ] - -- TODO why instruction could be the same in case with two binded functions? getInstrMap = M.fromList $ [ (pID, (pID, pDesc)) | Step{pID, pDesc} <- steps pr , isInstruction pDesc ] + getRels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr in and - [ checkIntermidiateToEndpointRelation getFuncMap getEpMap pr - , checkEndpointToInstructionRelation getFuncMap getInstrMap pr + [ checkEndpointToIntermidiateRelation getEpMap getInterMap getRels + , checkInstructionToEndpointRelation getInstrMap getEpMap getRels ] -checkFunctionToIntermidiateRelation pu fs = +-- TODO: remove? +checkIntermidiateToFunctionRelation pu fs = let fsVars = unionsMap variables fs puFuncVars = unionsMap variables $ getFBs (process pu) in fsVars == transferred pu && fsVars == puFuncVars -checkIntermidiateToEndpointRelation ifs eps pr = S.isSubsetOf makeRelationList fromRelation +checkEndpointToIntermidiateRelation eps ifs rels = S.isSubsetOf makeRelationList rels where - fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr makeRelationList = S.fromList $ concatMap @@ -77,10 +75,10 @@ checkIntermidiateToEndpointRelation ifs eps pr = S.isSubsetOf makeRelationList f $ M.elems ifs checkEndpointToInstructionRelation eps ins pr = +checkInstructionToEndpointRelation ins eps rels = let eps_ = M.fromList $ M.elems eps ins_ = M.fromList $ M.elems ins - fromRelation = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr checkRel (v1, v2) = case eps_ M.!? v1 of Just _ | Just (InstructionStep _) <- ins_ M.!? v2 -> [True] _ -> [] - in and $ concatMap checkRel fromRelation \ No newline at end of file + in and $ concatMap checkRel rels \ No newline at end of file diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index b6b02e915..912b8eba3 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -133,7 +133,7 @@ finitePUSynthesisProp name pu0 fsGen = return $ isProcessComplete pu fs && null (endpointOptions pu) - && checkIntegrityInternal pu + && checkIntegrity pu isProcessComplete pu fs = unionsMap variables fs == processedVars pu @@ -154,7 +154,7 @@ puCoSimProp name pu0 fsGen = return $ monadicIO $ run $ do - unless (isProcessComplete pu fs && checkIntegrityInternal pu) $ + unless (isProcessComplete pu fs && checkIntegrity pu) $ error $ "process is not complete: " <> incompleteProcessMsg pu fs i <- incrCounter 1 externalTestCntr wd <- getCurrentDirectory From db99ccceefcdd72fcd41c9115204ee783e4dfe99 Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Thu, 1 Apr 2021 03:17:36 +0300 Subject: [PATCH 17/49] refactor_integrity: fixed variable names --- src/NITTA/Model/IntegrityCheck.hs | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 760967bbd..bf83c14d4 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -23,7 +23,7 @@ import NITTA.Utils checkIntegrity pu = let pr = process pu getInterMap = - M.fromList $ + M.fromList [ (pID, (pID, f)) | step@Step{pID, pDesc} <- steps pr , isFB step @@ -43,7 +43,7 @@ checkIntegrity pu = _ -> [] ] getInstrMap = - M.fromList $ + M.fromList [ (pID, (pID, pDesc)) | Step{pID, pDesc} <- steps pr , isInstruction pDesc @@ -54,13 +54,6 @@ checkIntegrity pu = , checkInstructionToEndpointRelation getInstrMap getEpMap getRels ] --- TODO: remove? -checkIntermidiateToFunctionRelation pu fs = - let fsVars = unionsMap variables fs - puFuncVars = unionsMap variables $ getFBs (process pu) - in fsVars == transferred pu - && fsVars == puFuncVars - checkEndpointToIntermidiateRelation eps ifs rels = S.isSubsetOf makeRelationList rels where makeRelationList = @@ -74,11 +67,14 @@ checkEndpointToIntermidiateRelation eps ifs rels = S.isSubsetOf makeRelationList ) $ M.elems ifs -checkEndpointToInstructionRelation eps ins pr = -checkInstructionToEndpointRelation ins eps rels = - let eps_ = M.fromList $ M.elems eps - ins_ = M.fromList $ M.elems ins - checkRel (v1, v2) = case eps_ M.!? v1 of - Just _ | Just (InstructionStep _) <- ins_ M.!? v2 -> [True] - _ -> [] - in and $ concatMap checkRel rels \ No newline at end of file +checkInstructionToEndpointRelation ins eps rels = and makeRelationList + where + eps' = M.fromList $ M.elems eps + ins' = M.fromList $ M.elems ins + makeRelationList = + concatMap + ( \(r1, r2) -> case eps' M.!? r1 of + Just _ | (InstructionStep _) <- ins' M.! r2 -> [True] + _ -> [] + ) + rels From e695be7152aad6f68374791fedd574be8342a7ee Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Sun, 4 Apr 2021 16:47:01 +0300 Subject: [PATCH 18/49] fix_integrity: fixed two same keys bug --- src/NITTA/Model/IntegrityCheck.hs | 25 +++++++++++++++++-------- src/NITTA/Model/ProcessorUnits/Types.hs | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index bf83c14d4..ae7cc866f 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -19,6 +19,7 @@ import qualified Data.Set as S import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits import NITTA.Utils +import Safe checkIntegrity pu = let pr = process pu @@ -33,9 +34,9 @@ checkIntegrity pu = ] --- TODO what if we have 2 same variables? The key will be only one getEpMap = - M.fromList $ + M.fromListWith (++) $ concat - [ concatMap (\v -> [(v, (pID, ep))]) $ variables ep + [ concatMap (\v -> [(v, [(pID, ep)])]) $ variables ep | step@Step{pID, pDesc} <- steps pr , isEndpoint step , ep <- case pDesc of @@ -48,28 +49,36 @@ checkIntegrity pu = | Step{pID, pDesc} <- steps pr , isInstruction pDesc ] - getRels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr in and - [ checkEndpointToIntermidiateRelation getEpMap getInterMap getRels - , checkInstructionToEndpointRelation getInstrMap getEpMap getRels + [ checkEndpointToIntermidiateRelation getEpMap getInterMap pr + , checkInstructionToEndpointRelation getInstrMap getEpMap pr + , True + , True ] checkEndpointToIntermidiateRelation eps ifs rels = S.isSubsetOf makeRelationList rels +checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList rels where + rels = S.fromList $ relations pr + findRel (h, l) = + if length l > 1 + then Vertical h $ fst $ findJust (\(k, _) -> Vertical h k `elem` rels) l + else Vertical h $ fst $ head l makeRelationList = S.fromList $ concatMap ( \(h, f) -> concatMap - ( \v -> [(h, fst (eps M.! v))] + ( \v -> [findRel (h, eps M.! v)] ) $ variables f ) $ M.elems ifs -checkInstructionToEndpointRelation ins eps rels = and makeRelationList +checkInstructionToEndpointRelation ins eps pr = and makeRelationList where - eps' = M.fromList $ M.elems eps + rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr + eps' = M.fromList $ concat $ M.elems eps ins' = M.fromList $ M.elems ins makeRelationList = concatMap diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index 9e4d83916..0c0468bb5 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -208,7 +208,7 @@ data Relation -- step (function execution) can be translated to a sequence of endpoint -- steps (receiving and sending variable), and process unit instructions. Vertical ProcessStepID ProcessStepID - deriving (Show, Eq, Generic) + deriving (Show, Eq, Generic, Ord) instance ToJSON Relation From c33d8266eb60446ac96498134a95ae921aa43a2b Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Mon, 5 Apr 2021 21:11:35 +0300 Subject: [PATCH 19/49] feat_integrity: added broken test prototype --- src/NITTA/Model/ProcessorUnits/Broken.hs | 17 ++++++++++++----- test/NITTA/Model/ProcessorUnits/Broken/Tests.hs | 9 +++++++++ test/NITTA/Model/ProcessorUnits/Tests/Utils.hs | 4 +++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Broken.hs b/src/NITTA/Model/ProcessorUnits/Broken.hs index 73e577c00..aa4f35fec 100644 --- a/src/NITTA/Model/ProcessorUnits/Broken.hs +++ b/src/NITTA/Model/ProcessorUnits/Broken.hs @@ -64,6 +64,8 @@ data Broken v x t = Broken , -- |lost source endpoint due synthesis lostEndpointSource :: Bool , wrongAttr :: Bool + , -- | lost vertical relation + lostVerticalRelation :: Bool , unknownDataOut :: Bool } @@ -117,11 +119,13 @@ instance (VarValTime v x t) => EndpointProblem (Broken v x t) v t where | not $ null remain = concatMap (endpointOptions . execution pu) $ tail remain endpointOptions pu@Broken{remain} = concatMap (endpointOptions . execution pu) remain - endpointDecision pu@Broken{targets = [v], currentWorkEndpoints, wrongControlOnPush} d@EndpointSt{epRole = Target v', epAt} + endpointDecision pu@Broken{targets = [v], currentWorkEndpoints, wrongControlOnPush, lostVerticalRelation} d@EndpointSt{epRole = Target v', epAt} | v == v' , let (newEndpoints, process_') = runSchedule pu $ do updateTick (sup epAt) - scheduleEndpoint d $ scheduleInstruction (shiftI (if wrongControlOnPush then 1 else 0) epAt) Load = + let ins = scheduleInstruction (shiftI (if wrongControlOnPush then 1 else 0) epAt) Load + let ins' = if lostVerticalRelation then fmap (const []) ins else ins + scheduleEndpoint d ins' = pu { process_ = process_' , targets = [] @@ -129,17 +133,19 @@ instance (VarValTime v x t) => EndpointProblem (Broken v x t) v t where , doneAt = Just $ sup epAt + 3 } endpointDecision - pu@Broken{targets = [], sources, doneAt, currentWork = Just (a, f), currentWorkEndpoints, wrongControlOnPull} + pu@Broken{targets = [], sources, doneAt, currentWork = Just (a, f), currentWorkEndpoints, wrongControlOnPull, lostVerticalRelation} d@EndpointSt{epRole = Source v, epAt} | not $ null sources , let sources' = sources \\ elems v , sources' /= sources , let (newEndpoints, process_') = runSchedule pu $ do - endpoints <- scheduleEndpoint d $ scheduleInstruction (shiftI (if wrongControlOnPull then 0 else -1) epAt) Out + let ins = scheduleInstruction (shiftI (if wrongControlOnPull then 0 else -1) epAt) Out + let res = scheduleEndpoint d $ if lostVerticalRelation then fmap (const []) ins else ins + endpoints <- res when (null sources') $ do high <- scheduleFunction (a ... sup epAt) f let low = endpoints ++ currentWorkEndpoints - establishVerticalRelations high low + uncurry establishVerticalRelations $ if lostVerticalRelation then ([], []) else (high, low) updateTick (sup epAt + 1) return endpoints = pu @@ -201,6 +207,7 @@ instance (Time t) => Default (Broken v x t) where , lostEndpointTarget = False , lostEndpointSource = False , wrongAttr = False + , lostVerticalRelation = False , unknownDataOut = False } diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index 4e9e750a3..dfe288cb7 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -109,6 +109,15 @@ tests = , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost source endpoint" (maBroken u{lostEndpointSource = True}) alg , expectFail $ typedLuaTestCase (maBroken def{lostEndpointSource = True}) pInt "typedLuaTestCase lost source endpoint" lua ] + , testGroup + "broken relations integrity check" + -- at first positive test: it has good relation and checkIntegrity True + -- at second negative test for same pu: it has bad relation and checkIntegrity False + [ expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen + , expectFail $ puCoSimProp "puCoSimProp lost relations" u{lostVerticalRelation = True} fsGen + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost relations" (maBroken u{lostVerticalRelation = True}) alg + , expectFail $ typedLuaTestCase (maBroken def{lostVerticalRelation = True}) pInt "typedLuaTestCase lost relations" lua + ] ] where u = def :: Broken String Int Int diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index 912b8eba3..58e40a4a4 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -154,8 +154,10 @@ puCoSimProp name pu0 fsGen = return $ monadicIO $ run $ do - unless (isProcessComplete pu fs && checkIntegrity pu) $ + unless (isProcessComplete pu fs) $ error $ "process is not complete: " <> incompleteProcessMsg pu fs + unless (checkIntegrity pu) $ + error "fail at integrity check" i <- incrCounter 1 externalTestCntr wd <- getCurrentDirectory let pTargetProjectPath = joinPath [wd, "gen", toModuleName name <> "_" <> show i] From 4d58d750ad074fd7b3b486aae96b76f9e29b0c6d Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Mon, 5 Apr 2021 21:36:23 +0300 Subject: [PATCH 20/49] fix_integrity: removed pid and fixed wrong functions --- src/NITTA/Model/IntegrityCheck.hs | 11 ++++------- test/NITTA/Model/ProcessorUnits/Broken/Tests.hs | 4 ---- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index ae7cc866f..3b3ca47ff 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -25,14 +25,13 @@ checkIntegrity pu = let pr = process pu getInterMap = M.fromList - [ (pID, (pID, f)) + [ (pID, f) | step@Step{pID, pDesc} <- steps pr , isFB step , f <- case pDesc of (FStep f) -> [f] _ -> [] ] - --- TODO what if we have 2 same variables? The key will be only one getEpMap = M.fromListWith (++) $ concat @@ -45,7 +44,7 @@ checkIntegrity pu = ] getInstrMap = M.fromList - [ (pID, (pID, pDesc)) + [ (pID, pDesc) | Step{pID, pDesc} <- steps pr , isInstruction pDesc ] @@ -56,7 +55,6 @@ checkIntegrity pu = , True ] -checkEndpointToIntermidiateRelation eps ifs rels = S.isSubsetOf makeRelationList rels checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList rels where rels = S.fromList $ relations pr @@ -73,17 +71,16 @@ checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList r ) $ variables f ) - $ M.elems ifs + $ M.toList ifs checkInstructionToEndpointRelation ins eps pr = and makeRelationList where rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr eps' = M.fromList $ concat $ M.elems eps - ins' = M.fromList $ M.elems ins makeRelationList = concatMap ( \(r1, r2) -> case eps' M.!? r1 of - Just _ | (InstructionStep _) <- ins' M.! r2 -> [True] + Just _ | (InstructionStep _) <- ins M.! r2 -> [True] _ -> [] ) rels diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index dfe288cb7..125d4a74a 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -111,12 +111,8 @@ tests = ] , testGroup "broken relations integrity check" - -- at first positive test: it has good relation and checkIntegrity True - -- at second negative test for same pu: it has bad relation and checkIntegrity False [ expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost relations" u{lostVerticalRelation = True} fsGen - , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost relations" (maBroken u{lostVerticalRelation = True}) alg - , expectFail $ typedLuaTestCase (maBroken def{lostVerticalRelation = True}) pInt "typedLuaTestCase lost relations" lua ] ] where From 3e5ff0cd71e9746f2dac0a20d008afee4ab8da34 Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Wed, 7 Apr 2021 16:01:12 +0300 Subject: [PATCH 21/49] Remove unnecessary code duplication in Fram --- src/NITTA/Model/ProcessorUnits/Fram.hs | 36 ++++++++++---------------- src/NITTA/Utils.hs | 10 +------ src/NITTA/Utils/ProcessDescription.hs | 23 ++++++++++++++++ 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Fram.hs b/src/NITTA/Model/ProcessorUnits/Fram.hs index 87077e43d..437078ae5 100644 --- a/src/NITTA/Model/ProcessorUnits/Fram.hs +++ b/src/NITTA/Model/ProcessorUnits/Fram.hs @@ -301,7 +301,7 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where in fromRemain ++ fromCells -- Constant - endpointDecision fram@Fram{memory, process_} d@EndpointSt{epRole = Source vs, epAt} + endpointDecision fram@Fram{memory} d@EndpointSt{epRole = Source vs, epAt} | Just (addr, cell@Cell{state = DoConstant vs', job = Just Job{function, binds}}) <- L.find ( \case @@ -312,12 +312,9 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where let vsRemain = vs' L.\\ S.elems vs ((), process_') = runSchedule fram $ do updateTick (sup epAt + 1) - eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr - when (null vsRemain) $ do - fPID <- scheduleFunction (0 ... sup epAt) function - establishVerticalRelations binds fPID - let low = eps ++ map pID (relatedEndpoints process_ $ variables function) - establishVerticalRelations fPID low + void $ scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr + when (null vsRemain) $ + scheduleFunctionFinish binds function $ 0 ... sup epAt cell' = case vsRemain of [] -> cell @@ -345,11 +342,8 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where (_endpoints, process_) = runSchedule fram $ do updateTick (sup epAt + 1) eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr - when (null vsRemain) $ do - fPID <- scheduleFunction (0 ... sup epAt) function - establishVerticalRelations binds fPID - let low = eps ++ map pID (relatedEndpoints process_ $ variables function) - establishVerticalRelations fPID low + when (null vsRemain) $ + scheduleFunctionFinish binds function $ 0 ... sup epAt return eps cell' = if not $ null vsRemain @@ -368,12 +362,11 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where | Just (addr, cell@Cell{job = Just Job{function, binds}}) <- L.find (\case (_, Cell{state = DoLoopTarget v'}) -> v == v'; _ -> False) $ A.assocs memory = let ((), process_) = runSchedule fram $ do - eps <- scheduleEndpoint d $ scheduleInstruction epAt $ Write addr + void $ scheduleEndpoint d $ scheduleInstruction epAt $ Write addr updateTick (sup epAt + 1) - fPID <- scheduleFunction epAt function - establishVerticalRelations binds fPID - let low = eps ++ map pID (relatedEndpoints process_ $ variables function) - establishVerticalRelations fPID low + + scheduleFunctionFinish binds function epAt + cell' = cell { job = Nothing @@ -413,12 +406,9 @@ instance (VarValTime v x t) => EndpointProblem (Fram v x t) v t where let vsRemain = vs' L.\\ S.elems vs ((), process_) = runSchedule fram $ do updateTick (sup epAt + 1) - eps <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr - when (null vsRemain) $ do - fPID <- scheduleFunction (fBegin ... sup epAt) function - establishVerticalRelations binds fPID - let low = eps ++ map pID (relatedEndpoints process_ $ variables function) - establishVerticalRelations fPID low + void $ scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) $ PrepareRead addr + when (null vsRemain) $ + scheduleFunctionFinish binds function $ fBegin ... sup epAt cell' = case vsRemain of [] -> cell diff --git a/src/NITTA/Utils.hs b/src/NITTA/Utils.hs index 648ac906c..6c3a538e9 100644 --- a/src/NITTA/Utils.hs +++ b/src/NITTA/Utils.hs @@ -45,12 +45,12 @@ import Control.Monad.State (State, modify') import Data.Bits (setBit, testBit) import Data.List (sortOn) import Data.Maybe (isJust, mapMaybe) -import qualified Data.Set as S import qualified Data.String.Utils as S import qualified Data.Text as T import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits.Types import NITTA.Utils.Base +import NITTA.Utils.ProcessDescription import Numeric (readInt, showHex) import Numeric.Interval.NonEmpty (inf, sup, (...)) import qualified Numeric.Interval.NonEmpty as I @@ -129,14 +129,6 @@ stepsInterval ss = b = maximum $ map (sup . pInterval) ss in a ... b -relatedEndpoints process_ vs = - filter - ( \case - Step{pDesc = EndpointRoleStep role} -> not $ null (variables role `S.intersection` vs) - _ -> False - ) - $ steps process_ - isInstruction (InstructionStep _) = True isInstruction _ = False diff --git a/src/NITTA/Utils/ProcessDescription.hs b/src/NITTA/Utils/ProcessDescription.hs index cccb6601a..4ffe32946 100644 --- a/src/NITTA/Utils/ProcessDescription.hs +++ b/src/NITTA/Utils/ProcessDescription.hs @@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} {- | @@ -25,19 +26,23 @@ module NITTA.Utils.ProcessDescription ( scheduleFunctionBind, scheduleFunctionRevoke, scheduleFunction, + scheduleFunctionFinish, scheduleInstruction, scheduleInstruction_, scheduleNestedStep, establishVerticalRelations, establishVerticalRelation, getProcessSlice, + relatedEndpoints, castInstruction, updateTick, -- TODO: must be hidded ) where import Control.Monad.State import Data.Proxy (asProxyTypeOf) +import qualified Data.Set as S import Data.Typeable +import NITTA.Intermediate.Types import NITTA.Model.Problems import NITTA.Model.ProcessorUnits.Types import Numeric.Interval.NonEmpty (singleton) @@ -133,6 +138,16 @@ scheduleFunctionRevoke f = do -- |Add to the process description information about function evaluation. scheduleFunction ti f = scheduleStep ti $ FStep f +{- |Schedule function and establish vertical relations between bind step, +function step, and all related endpoints. +-} +scheduleFunctionFinish bPID function at = do + fPID <- scheduleFunction at function + establishVerticalRelations bPID fPID + process_ <- getProcessSlice + let low = map pID $ relatedEndpoints process_ $ variables function + establishVerticalRelations fPID low + {- |Add to the process description information about endpoint behaviour, and it's low-level implementation (on instruction level). Vertical relations connect endpoint level and instruction level steps. @@ -164,6 +179,14 @@ getProcessSlice = do Schedule{schProcess} <- get return schProcess +relatedEndpoints process_ vs = + filter + ( \case + Step{pDesc = EndpointRoleStep role} -> not $ null (variables role `S.intersection` vs) + _ -> False + ) + $ steps process_ + -- |Helper for instruction extraction from a rigid type variable. castInstruction :: (Typeable a, Typeable pu) => pu -> a -> Maybe (Instruction pu) castInstruction _pu i = cast i From 169c21d33407fcf164bc734b935154738a75df6e Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Wed, 7 Apr 2021 16:04:44 +0300 Subject: [PATCH 22/49] Migrate to `scheduleFunctionFinish` --- src/NITTA/Model/ProcessorUnits/Accum.hs | 7 +++---- src/NITTA/Model/ProcessorUnits/Broken.hs | 1 + src/NITTA/Model/ProcessorUnits/Multiplier.hs | 7 ++++--- src/NITTA/Model/ProcessorUnits/Shift.hs | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Accum.hs b/src/NITTA/Model/ProcessorUnits/Accum.hs index 0d081cdda..165e19a88 100644 --- a/src/NITTA/Model/ProcessorUnits/Accum.hs +++ b/src/NITTA/Model/ProcessorUnits/Accum.hs @@ -188,10 +188,9 @@ instance (VarValTime v x t, Num x) => EndpointProblem (Accum v x t) v t where (_, process_') = runSchedule pu $ do endpoints <- scheduleEndpoint d $ scheduleInstruction (epAt -1) Out when (null tasks') $ do - high <- scheduleFunction (a ... sup epAt) func - let low = endpoints ++ map pID (relatedEndpoints process_ $ variables func) - establishVerticalRelations high low - + -- FIXME: here ([]) you can see the source of error. + -- Function don't connected to bind step. It should be fixed. + scheduleFunctionFinish [] func $ a ... sup epAt updateTick (sup epAt) return endpoints in pu diff --git a/src/NITTA/Model/ProcessorUnits/Broken.hs b/src/NITTA/Model/ProcessorUnits/Broken.hs index aa4f35fec..917d8a311 100644 --- a/src/NITTA/Model/ProcessorUnits/Broken.hs +++ b/src/NITTA/Model/ProcessorUnits/Broken.hs @@ -143,6 +143,7 @@ instance (VarValTime v x t) => EndpointProblem (Broken v x t) v t where let res = scheduleEndpoint d $ if lostVerticalRelation then fmap (const []) ins else ins endpoints <- res when (null sources') $ do + -- TODO: migrate to scheduleFunctionFinish high <- scheduleFunction (a ... sup epAt) f let low = endpoints ++ currentWorkEndpoints uncurry establishVerticalRelations $ if lostVerticalRelation then ([], []) else (high, low) diff --git a/src/NITTA/Model/ProcessorUnits/Multiplier.hs b/src/NITTA/Model/ProcessorUnits/Multiplier.hs index 06734ea75..c3f3f87d7 100644 --- a/src/NITTA/Model/ProcessorUnits/Multiplier.hs +++ b/src/NITTA/Model/ProcessorUnits/Multiplier.hs @@ -528,11 +528,12 @@ instance (VarValTime v x t) => EndpointProblem (Multiplier v x t) v t where let (_, process_') = runSchedule pu $ do endpoints <- scheduleEndpoint d $ scheduleInstruction epAt Out when (null sources') $ do - high <- scheduleFunction (a ... sup epAt) f - let low = endpoints ++ map pID (relatedEndpoints process_ $ variables f) -- Set up the vertical relantions between functional unit -- and related to that data sending. - establishVerticalRelations high low + + -- FIXME: here ([]) you can see the source of error. + -- Function don't connected to bind step. It should be fixed. + scheduleFunctionFinish [] f $ a ... sup epAt -- this is needed to correct work of automatically generated tests -- that takes time about time from Process updateTick (sup epAt) diff --git a/src/NITTA/Model/ProcessorUnits/Shift.hs b/src/NITTA/Model/ProcessorUnits/Shift.hs index ee94508cf..153ce9d8d 100644 --- a/src/NITTA/Model/ProcessorUnits/Shift.hs +++ b/src/NITTA/Model/ProcessorUnits/Shift.hs @@ -189,9 +189,9 @@ instance (VarValTime v x t) => EndpointProblem (Shift v x t) v t where updateTick (sup epAt) endpoints <- scheduleEndpoint d $ scheduleInstruction (shiftI (-1) epAt) Out when (null sources') $ do - high <- scheduleFunction (a ... sup epAt) f - let low = endpoints ++ map pID (relatedEndpoints process_ $ variables f) - establishVerticalRelations high low + -- FIXME: here ([]) you can see the source of error. + -- Function don't connected to bind step. It should be fixed. + scheduleFunctionFinish [] f $ a ... sup epAt return endpoints in pu { process_ = process_' From f0a4e99310c75862dc466235e27e0372ca9bf3bb Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Wed, 7 Apr 2021 16:35:41 +0300 Subject: [PATCH 23/49] Add horizontal relations --- src/NITTA/Model/IntegrityCheck.hs | 4 ++-- src/NITTA/Model/Networks/Bus.hs | 7 ++++++- src/NITTA/Model/ProcessorUnits/Fram.hs | 3 ++- src/NITTA/Model/ProcessorUnits/Types.hs | 12 ++++++++++++ src/NITTA/Utils/ProcessDescription.hs | 16 +++++++++++++++- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 3b3ca47ff..98e43a176 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -57,7 +57,7 @@ checkIntegrity pu = checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList rels where - rels = S.fromList $ relations pr + rels = S.fromList $ filter isVertical $ relations pr findRel (h, l) = if length l > 1 then Vertical h $ fst $ findJust (\(k, _) -> Vertical h k `elem` rels) l @@ -75,7 +75,7 @@ checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList r checkInstructionToEndpointRelation ins eps pr = and makeRelationList where - rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ relations pr + rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr eps' = M.fromList $ concat $ M.elems eps makeRelationList = concatMap diff --git a/src/NITTA/Model/Networks/Bus.hs b/src/NITTA/Model/Networks/Bus.hs index 0a24638cd..a8a2e98c7 100644 --- a/src/NITTA/Model/Networks/Bus.hs +++ b/src/NITTA/Model/Networks/Bus.hs @@ -227,7 +227,12 @@ instance (UnitTag tag, VarValTime v x t) => ProcessorUnit (BusNetwork tag v x t) return (pID, pID') ) steps - mapM_ (\(Vertical h l) -> establishVerticalRelation (pu2netKey M.! h) (pu2netKey M.! l)) relations + mapM_ + ( \case + (Vertical h l) -> establishVerticalRelation (pu2netKey M.! h) (pu2netKey M.! l) + (Horizontal h l) -> establishHorizontalRelations [pu2netKey M.! h] [pu2netKey M.! l] + ) + relations instance Controllable (BusNetwork tag v x t) where data Instruction (BusNetwork tag v x t) diff --git a/src/NITTA/Model/ProcessorUnits/Fram.hs b/src/NITTA/Model/ProcessorUnits/Fram.hs index 437078ae5..dff6f9a0c 100644 --- a/src/NITTA/Model/ProcessorUnits/Fram.hs +++ b/src/NITTA/Model/ProcessorUnits/Fram.hs @@ -258,7 +258,8 @@ instance (VarValTime v x t) => BreakLoopProblem (Fram v x t) v x where revoke <- scheduleFunctionRevoke $ recLoop bl f1 <- scheduleFunctionBind $ recLoopOut bl f2 <- scheduleFunctionBind $ recLoopIn bl - establishVerticalRelations binds (f1 ++ f2 ++ revoke) + + establishHorizontalRelations binds (f1 ++ f2 ++ revoke) return (f1, f2) iJob = (defJob $ recLoopOut bl){binds = iPid, startAt = Just 0} oJob = (defJob $ recLoopIn bl){binds = oPid} diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index 0c0468bb5..e2d494679 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -33,6 +33,8 @@ module NITTA.Model.ProcessorUnits.Types ( Step (..), StepInfo (..), Relation (..), + isVertical, + isHorizontal, descent, whatsHappen, extractInstructionAt, @@ -208,8 +210,18 @@ data Relation -- step (function execution) can be translated to a sequence of endpoint -- steps (receiving and sending variable), and process unit instructions. Vertical ProcessStepID ProcessStepID + | -- |Horizontal relationships (on one level). For example, we bind the + -- function and apply the refactoring. The binding step should be + -- connected to refactoring steps, including new binding steps. + Horizontal ProcessStepID ProcessStepID deriving (Show, Eq, Generic, Ord) +isVertical Vertical{} = True +isVertical _ = False + +isHorizontal Horizontal{} = True +isHorizontal _ = False + instance ToJSON Relation whatsHappen t Process{steps} = filter (atSameTime t . pInterval) steps diff --git a/src/NITTA/Utils/ProcessDescription.hs b/src/NITTA/Utils/ProcessDescription.hs index 4ffe32946..d10c76389 100644 --- a/src/NITTA/Utils/ProcessDescription.hs +++ b/src/NITTA/Utils/ProcessDescription.hs @@ -32,6 +32,7 @@ module NITTA.Utils.ProcessDescription ( scheduleNestedStep, establishVerticalRelations, establishVerticalRelation, + establishHorizontalRelations, getProcessSlice, relatedEndpoints, castInstruction, @@ -104,7 +105,7 @@ scheduleStep' mkStep = do return [nextUid] {- |Add to the process description information about vertical relations, which are defined by the - Cartesian product of high and low lists. +Cartesian product of high and low lists. -} establishVerticalRelations high low = do sch@Schedule{schProcess = p@Process{relations}} <- get @@ -127,6 +128,19 @@ establishVerticalRelation h l = do } } +{- |Add to the process description information about horizontal relations (inside +level), which are defined by the Cartesian product of high and low lists. +-} +establishHorizontalRelations high low = do + sch@Schedule{schProcess = p@Process{relations}} <- get + put + sch + { schProcess = + p + { relations = [Horizontal h l | h <- high, l <- low] ++ relations + } + } + scheduleFunctionBind f = do Schedule{schProcess = Process{nextTick}} <- get scheduleStep (singleton nextTick) $ CADStep $ "bind " ++ show f From 8bdeacc47fc267395c3ac99f73f0977f254db525 Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Wed, 7 Apr 2021 16:37:55 +0300 Subject: [PATCH 24/49] Remove establishVerticalRelation (swap by establishVerticalRelations) --- src/NITTA/Model/Networks/Bus.hs | 6 +++--- src/NITTA/Utils/ProcessDescription.hs | 12 ------------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/NITTA/Model/Networks/Bus.hs b/src/NITTA/Model/Networks/Bus.hs index a8a2e98c7..224b37e15 100644 --- a/src/NITTA/Model/Networks/Bus.hs +++ b/src/NITTA/Model/Networks/Bus.hs @@ -200,7 +200,7 @@ instance (UnitTag tag, VarValTime v x t) => ProcessorUnit (BusNetwork tag v x t) mapM_ ( \(epKey, v) -> when (v `M.member` v2transportStepKey) $ - establishVerticalRelation (v2transportStepKey M.! v) epKey + establishVerticalRelations [v2transportStepKey M.! v] [epKey] ) enpointStepKeyVars @@ -210,7 +210,7 @@ instance (UnitTag tag, VarValTime v x t) => ProcessorUnit (BusNetwork tag v x t) mapM_ ( \v -> when (v `M.member` v2transportStepKey) $ - establishVerticalRelation pID (v2transportStepKey M.! v) + establishVerticalRelations [pID] [v2transportStepKey M.! v] ) $ variables f ) @@ -229,7 +229,7 @@ instance (UnitTag tag, VarValTime v x t) => ProcessorUnit (BusNetwork tag v x t) steps mapM_ ( \case - (Vertical h l) -> establishVerticalRelation (pu2netKey M.! h) (pu2netKey M.! l) + (Vertical h l) -> establishVerticalRelations [pu2netKey M.! h] [pu2netKey M.! l] (Horizontal h l) -> establishHorizontalRelations [pu2netKey M.! h] [pu2netKey M.! l] ) relations diff --git a/src/NITTA/Utils/ProcessDescription.hs b/src/NITTA/Utils/ProcessDescription.hs index d10c76389..e04ef3b6f 100644 --- a/src/NITTA/Utils/ProcessDescription.hs +++ b/src/NITTA/Utils/ProcessDescription.hs @@ -31,7 +31,6 @@ module NITTA.Utils.ProcessDescription ( scheduleInstruction_, scheduleNestedStep, establishVerticalRelations, - establishVerticalRelation, establishHorizontalRelations, getProcessSlice, relatedEndpoints, @@ -117,17 +116,6 @@ establishVerticalRelations high low = do } } --- |Add to the process description information about vertical relation. -establishVerticalRelation h l = do - sch@Schedule{schProcess = p@Process{relations}} <- get - put - sch - { schProcess = - p - { relations = Vertical h l : relations - } - } - {- |Add to the process description information about horizontal relations (inside level), which are defined by the Cartesian product of high and low lists. -} From de9f68bad92d989200122e51274809d26c2a529a Mon Sep 17 00:00:00 2001 From: qr-mipro Date: Tue, 6 Apr 2021 00:28:03 +0300 Subject: [PATCH 25/49] test_integrity: added puCoSim, finitePuSynth positive test --- test/NITTA/Model/ProcessorUnits/Broken/Tests.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index 125d4a74a..fdbbe179b 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -112,6 +112,9 @@ tests = , testGroup "broken relations integrity check" [ expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen + [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u{lostVerticalRelation = False} fsGen + , puCoSimProp "puCoSimProp relation positive test" u{lostVerticalRelation = False} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost relations" u{lostVerticalRelation = True} fsGen ] ] From ccc98793a70b3a4e5897e143d7de4c6a09abea83 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 11 Apr 2021 17:16:25 +0300 Subject: [PATCH 26/49] fix_integrity: fixed name, added tests --- src/NITTA/Model/IntegrityCheck.hs | 17 +++--- src/NITTA/Model/ProcessorUnits/Broken.hs | 58 ++++++++++++------- src/NITTA/Utils.hs | 3 - .../Model/ProcessorUnits/Broken/Tests.hs | 27 +++++++-- 4 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 98e43a176..db779c523 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -4,7 +4,7 @@ {- | Module : NITTA.Model.IntegrityCheck -Description : Tests vertical relations in PU +Description : Module for checking model description consistency Copyright : (c) Artyom Kostyuchik, 2021 License : BSD3 Maintainer : aleksandr.penskoi@gmail.com @@ -22,11 +22,10 @@ import NITTA.Utils import Safe checkIntegrity pu = - let pr = process pu - getInterMap = + let getInterMap = M.fromList [ (pID, f) - | step@Step{pID, pDesc} <- steps pr + | step@Step{pID, pDesc} <- steps $ process pu , isFB step , f <- case pDesc of (FStep f) -> [f] @@ -36,7 +35,7 @@ checkIntegrity pu = M.fromListWith (++) $ concat [ concatMap (\v -> [(v, [(pID, ep)])]) $ variables ep - | step@Step{pID, pDesc} <- steps pr + | step@Step{pID, pDesc} <- steps $ process pu , isEndpoint step , ep <- case pDesc of (EndpointRoleStep e) -> [e] @@ -45,14 +44,12 @@ checkIntegrity pu = getInstrMap = M.fromList [ (pID, pDesc) - | Step{pID, pDesc} <- steps pr + | Step{pID, pDesc} <- steps $ process pu , isInstruction pDesc ] in and - [ checkEndpointToIntermidiateRelation getEpMap getInterMap pr - , checkInstructionToEndpointRelation getInstrMap getEpMap pr - , True - , True + [ checkEndpointToIntermidiateRelation getEpMap getInterMap $ process pu + , checkInstructionToEndpointRelation getInstrMap getEpMap $ process pu ] checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList rels diff --git a/src/NITTA/Model/ProcessorUnits/Broken.hs b/src/NITTA/Model/ProcessorUnits/Broken.hs index 917d8a311..2c9b7ee61 100644 --- a/src/NITTA/Model/ProcessorUnits/Broken.hs +++ b/src/NITTA/Model/ProcessorUnits/Broken.hs @@ -26,7 +26,7 @@ module NITTA.Model.ProcessorUnits.Broken ( IOPorts (..), ) where -import Control.Monad (when) +import Control.Monad import Data.Default import Data.List (find, (\\)) import Data.Set (elems, fromList, member) @@ -64,8 +64,9 @@ data Broken v x t = Broken , -- |lost source endpoint due synthesis lostEndpointSource :: Bool , wrongAttr :: Bool - , -- | lost vertical relation - lostVerticalRelation :: Bool + , lostFunctionRelation :: Bool + , lostEndpointRelation :: Bool + , lostInstructionRelation :: Bool , unknownDataOut :: Bool } @@ -119,34 +120,47 @@ instance (VarValTime v x t) => EndpointProblem (Broken v x t) v t where | not $ null remain = concatMap (endpointOptions . execution pu) $ tail remain endpointOptions pu@Broken{remain} = concatMap (endpointOptions . execution pu) remain - endpointDecision pu@Broken{targets = [v], currentWorkEndpoints, wrongControlOnPush, lostVerticalRelation} d@EndpointSt{epRole = Target v', epAt} - | v == v' - , let (newEndpoints, process_') = runSchedule pu $ do - updateTick (sup epAt) - let ins = scheduleInstruction (shiftI (if wrongControlOnPush then 1 else 0) epAt) Load - let ins' = if lostVerticalRelation then fmap (const []) ins else ins - scheduleEndpoint d ins' = - pu - { process_ = process_' - , targets = [] - , currentWorkEndpoints = newEndpoints ++ currentWorkEndpoints - , doneAt = Just $ sup epAt + 3 - } endpointDecision - pu@Broken{targets = [], sources, doneAt, currentWork = Just (a, f), currentWorkEndpoints, wrongControlOnPull, lostVerticalRelation} + pu@Broken{targets = [v], currentWorkEndpoints, wrongControlOnPush, lostInstructionRelation, lostEndpointRelation} + d@EndpointSt{epRole = Target v', epAt} + | v == v' + , let (newEndpoints, process_') = runSchedule pu $ do + updateTick (sup epAt) + let ins = + if lostInstructionRelation + then return [] + else scheduleInstruction (shiftI (if wrongControlOnPush then 1 else 0) epAt) Load + if lostEndpointRelation then return [] else scheduleEndpoint d ins = + pu + { process_ = process_' + , targets = [] + , currentWorkEndpoints = newEndpoints ++ currentWorkEndpoints + , doneAt = Just $ sup epAt + 3 + } + endpointDecision + pu@Broken{targets = [], sources, doneAt, currentWork = Just (a, f), currentWorkEndpoints, wrongControlOnPull, lostInstructionRelation, lostEndpointRelation, lostFunctionRelation} d@EndpointSt{epRole = Source v, epAt} | not $ null sources , let sources' = sources \\ elems v , sources' /= sources , let (newEndpoints, process_') = runSchedule pu $ do - let ins = scheduleInstruction (shiftI (if wrongControlOnPull then 0 else -1) epAt) Out - let res = scheduleEndpoint d $ if lostVerticalRelation then fmap (const []) ins else ins + let ins = + if lostInstructionRelation + then return [] + else scheduleInstruction (shiftI (if wrongControlOnPull then 0 else -1) epAt) Out + let res = + if lostEndpointRelation + then return [] + else scheduleEndpoint d ins endpoints <- res when (null sources') $ do -- TODO: migrate to scheduleFunctionFinish high <- scheduleFunction (a ... sup epAt) f + --if lostFunctionRelation + -- then return [] + -- else let low = endpoints ++ currentWorkEndpoints - uncurry establishVerticalRelations $ if lostVerticalRelation then ([], []) else (high, low) + unless lostFunctionRelation $ uncurry establishVerticalRelations (high, low) updateTick (sup epAt + 1) return endpoints = pu @@ -208,7 +222,9 @@ instance (Time t) => Default (Broken v x t) where , lostEndpointTarget = False , lostEndpointSource = False , wrongAttr = False - , lostVerticalRelation = False + , lostFunctionRelation = False + , lostEndpointRelation = False + , lostInstructionRelation = False , unknownDataOut = False } diff --git a/src/NITTA/Utils.hs b/src/NITTA/Utils.hs index 6c3a538e9..8b3a95545 100644 --- a/src/NITTA/Utils.hs +++ b/src/NITTA/Utils.hs @@ -35,7 +35,6 @@ module NITTA.Utils ( stepsInterval, relatedEndpoints, isFB, - getFBs, isEndpoint, isInstruction, module NITTA.Utils.Base, @@ -112,8 +111,6 @@ isFB s = isJust $ getFB s getFB Step{pDesc} | FStep fb <- descent pDesc = Just fb getFB _ = Nothing -getFBs p = mapMaybe getFB $ sortOn stepStart $ steps p - isEndpoint ep = isJust $ getEndpoint ep getEndpoint Step{pDesc} | EndpointRoleStep role <- descent pDesc = Just role diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index fdbbe179b..2be29f55b 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -111,11 +111,28 @@ tests = ] , testGroup "broken relations integrity check" - [ expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen - [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u{lostVerticalRelation = False} fsGen - , puCoSimProp "puCoSimProp relation positive test" u{lostVerticalRelation = False} fsGen - , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost relations" u{lostVerticalRelation = True} fsGen - , expectFail $ puCoSimProp "puCoSimProp lost relations" u{lostVerticalRelation = True} fsGen + [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u fsGen + , puCoSimProp "puCoSimProp relation positive test" u fsGen + , --- TODO fix case when we have lost Intstruction but integrityCheck is OK + expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost instr and ep" u{lostInstructionRelation = True, lostEndpointRelation = True} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Endpoints" u{lostEndpointRelation = True} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Instruction" u{lostInstructionRelation = True} fsGen + , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen + , expectFail $ puCoSimProp "puCoSimProp lost Endpoints" u{lostEndpointRelation = True} fsGen + , expectFail $ puCoSimProp "puCoSimProp lost Instruction" u{lostInstructionRelation = True} fsGen + ] + , testGroup + --"broken relations coSimTest" + "broken relations integrity check" + [ nittaCoSimTestCase "nittaCoSimTestCase positive test" (maBroken u) alg + , typedLuaTestCase (maBroken def) pInt "typedLuaTestCase positive test" lua + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Endpoints" (maBroken u{lostEndpointRelation = True}) alg + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Instruction" (maBroken u{lostInstructionRelation = True}) alg + , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua + , expectFail $ typedLuaTestCase (maBroken def{lostEndpointRelation = True}) pInt "typedLuaTestCase lost Endpoints" lua + , expectFail $ typedLuaTestCase (maBroken def{lostInstructionRelation = True}) pInt "typedLuaTestCase lost Instruction" lua ] ] where From f6bd3fe57d0c01bf58828e4432919a6737c7433d Mon Sep 17 00:00:00 2001 From: artyom Date: Mon, 12 Apr 2021 05:34:35 +0300 Subject: [PATCH 27/49] feat_integrity: updated Utils API --- src/NITTA/Model/Networks/Bus.hs | 4 ++-- src/NITTA/Utils.hs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/NITTA/Model/Networks/Bus.hs b/src/NITTA/Model/Networks/Bus.hs index 224b37e15..705c0ab59 100644 --- a/src/NITTA/Model/Networks/Bus.hs +++ b/src/NITTA/Model/Networks/Bus.hs @@ -177,8 +177,8 @@ instance (UnitTag tag, VarValTime v x t) => ProcessorUnit (BusNetwork tag v x t) let v2transportStepKey = M.fromList [ (v, pID) - | Step{pID, pDesc} <- steps bnProcess - , isInstruction pDesc + | step@Step{pID, pDesc} <- steps bnProcess + , isInstruction step , v <- case pDesc of (InstructionStep ins) | Just (Transport var _ _) <- castInstruction net ins -> [var] _ -> [] diff --git a/src/NITTA/Utils.hs b/src/NITTA/Utils.hs index 8b3a95545..640c4ff08 100644 --- a/src/NITTA/Utils.hs +++ b/src/NITTA/Utils.hs @@ -29,6 +29,10 @@ module NITTA.Utils ( -- *Process inspection endpointAt, + getEndpoint, + getFunction, + getInstruction, + getCAD, getEndpoints, transferred, inputsPushedAt, @@ -116,6 +120,17 @@ isEndpoint ep = isJust $ getEndpoint ep getEndpoint Step{pDesc} | EndpointRoleStep role <- descent pDesc = Just role getEndpoint _ = Nothing +getFunction Step{pDesc} | FStep role <- descent pDesc = Just role +getFunction _ = Nothing + +isInstruction instr = isJust $ getInstruction instr + +getInstruction Step{pDesc} | role@(InstructionStep _) <- descent pDesc = Just role +getInstruction _ = Nothing + +getCAD Step{pDesc} | CADStep role <- descent pDesc = Just role +getCAD _ = Nothing + getEndpoints p = mapMaybe getEndpoint $ sortOn stepStart $ steps p transferred pu = unionsMap variables $ getEndpoints $ process pu @@ -126,7 +141,4 @@ stepsInterval ss = b = maximum $ map (sup . pInterval) ss in a ... b -isInstruction (InstructionStep _) = True -isInstruction _ = False - stepStart Step{pInterval} = I.inf pInterval From 00d70f33e569c96bd4d433f58e94656829ff91d8 Mon Sep 17 00:00:00 2001 From: artyom Date: Mon, 12 Apr 2021 07:38:04 +0300 Subject: [PATCH 28/49] feat_integrity: added prototype for vertical CAD function check --- src/NITTA/Model/IntegrityCheck.hs | 37 ++++++++++++++++++- .../Model/ProcessorUnits/Broken/Tests.hs | 29 ++++++++++----- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index db779c523..319e77425 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -47,15 +47,48 @@ checkIntegrity pu = | Step{pID, pDesc} <- steps $ process pu , isInstruction pDesc ] + -- (pid, f) + getCadFunctions = + let filterCad (_, f) + | Just Loop{} <- castF f = True + | Just (LoopBegin Loop{} _) <- castF f = True + | Just (LoopEnd Loop{} _) <- castF f = True + | otherwise = False + in M.fromList $ filter filterCad $ M.toList getInterMap + + -- (Loop (pid, f)) , where Loop is show instance + -- TODO: add nothing + getCadSteps = + M.fromList $ + concat + [ concatMap (\l -> [(l, (pID, step))]) pDesc' + | step@Step{pID} <- steps $ process pu + , pDesc' <- case getCAD step of + Just msg -> [msg] + _ -> [] + ] in and [ checkEndpointToIntermidiateRelation getEpMap getInterMap $ process pu , checkInstructionToEndpointRelation getInstrMap getEpMap $ process pu + , checkCadToFunctionRelation getCadFunctions getCadSteps $ process pu ] -checkEndpointToIntermidiateRelation eps ifs pr = S.isSubsetOf makeRelationList rels +-- every function should be binded to CAD step +-- at the moment check LoopBegin/End +checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels where rels = S.fromList $ filter isVertical $ relations pr - findRel (h, l) = + showLoop f = "bind " <> show f + makeCadVertical = + S.fromList $ + concatMap + ( \(h, f) -> + concatMap + ( \v -> [uncurry Vertical (h, fst $ cadSt M.! v)] + ) + $ showLoop f + ) + $ M.toList cadFs if length l > 1 then Vertical h $ fst $ findJust (\(k, _) -> Vertical h k `elem` rels) l else Vertical h $ fst $ head l diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index 2be29f55b..7dfc56ca0 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -111,29 +111,38 @@ tests = ] , testGroup "broken relations integrity check" - [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u fsGen - , puCoSimProp "puCoSimProp relation positive test" u fsGen - , --- TODO fix case when we have lost Intstruction but integrityCheck is OK + [ nittaCoSimTestCase "nittaCoSimTestCase positive test" (maBroken u) alg + , typedLuaTestCase (maBroken def) pInt "typedLuaTestCase positive test" lua + , puCoSimTestCase "puCoSimTestCase positive test" u [("a", 42)] [brokenBuffer "a" ["b"]] + ] + , testGroup + "broken relations integrity check" + [ --- TODO fix case when we have lost Intstruction but integrityCheck is OK expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost instr and ep" u{lostInstructionRelation = True, lostEndpointRelation = True} fsGen - , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Endpoints" u{lostEndpointRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Instruction" u{lostInstructionRelation = True} fsGen - , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost Endpoints" u{lostEndpointRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost Instruction" u{lostInstructionRelation = True} fsGen ] , testGroup - --"broken relations coSimTest" "broken relations integrity check" - [ nittaCoSimTestCase "nittaCoSimTestCase positive test" (maBroken u) alg - , typedLuaTestCase (maBroken def) pInt "typedLuaTestCase positive test" lua - , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg + [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Instructions" u{lostInstructionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Endpoints" (maBroken u{lostEndpointRelation = True}) alg , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Instruction" (maBroken u{lostInstructionRelation = True}) alg - , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua , expectFail $ typedLuaTestCase (maBroken def{lostEndpointRelation = True}) pInt "typedLuaTestCase lost Endpoints" lua , expectFail $ typedLuaTestCase (maBroken def{lostInstructionRelation = True}) pInt "typedLuaTestCase lost Instruction" lua ] + , testGroup + "broken relations integrity check fails" + [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u fsGen + , puCoSimProp "puCoSimProp relation positive test" u fsGen + , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg + , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua + ] ] where u = def :: Broken String Int Int From af3f88aa42f70f7c984c7d43913dcb96e7210a81 Mon Sep 17 00:00:00 2001 From: artyom Date: Mon, 12 Apr 2021 16:59:56 +0300 Subject: [PATCH 29/49] fix_integrity: reworked get.*Map functions, returned old implementation for Broken epDecision --- src/NITTA/Model/IntegrityCheck.hs | 65 ++++++++++++++++-------- src/NITTA/Model/ProcessorUnits/Broken.hs | 10 ++-- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 319e77425..449e10a72 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -14,39 +14,44 @@ module NITTA.Model.IntegrityCheck ( checkIntegrity, ) where +import Data.List (find) import qualified Data.Map.Strict as M import qualified Data.Set as S +import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.ProcessorUnits import NITTA.Utils -import Safe checkIntegrity pu = let getInterMap = M.fromList [ (pID, f) - | step@Step{pID, pDesc} <- steps $ process pu + | step@Step{pID} <- steps $ process pu , isFB step - , f <- case pDesc of - (FStep f) -> [f] + , f <- case getFunction step of + Just f -> [f] _ -> [] ] getEpMap = M.fromListWith (++) $ concat [ concatMap (\v -> [(v, [(pID, ep)])]) $ variables ep - | step@Step{pID, pDesc} <- steps $ process pu + | step@Step{pID} <- steps $ process pu , isEndpoint step - , ep <- case pDesc of - (EndpointRoleStep e) -> [e] + , ep <- case getEndpoint step of + Just e -> [e] _ -> [] ] getInstrMap = M.fromList - [ (pID, pDesc) - | Step{pID, pDesc} <- steps $ process pu - , isInstruction pDesc + [ (pID, instr) + | step@Step{pID} <- steps $ process pu + , isInstruction step + , instr <- case getInstruction step of + Just i -> [i] + _ -> [] ] + -- (pid, f) getCadFunctions = let filterCad (_, f) @@ -56,8 +61,8 @@ checkIntegrity pu = | otherwise = False in M.fromList $ filter filterCad $ M.toList getInterMap + -- TODO: add Maybe? -- (Loop (pid, f)) , where Loop is show instance - -- TODO: add nothing getCadSteps = M.fromList $ concat @@ -68,12 +73,12 @@ checkIntegrity pu = _ -> [] ] in and + -- TODO: why so much calls(prints) in tests? [ checkEndpointToIntermidiateRelation getEpMap getInterMap $ process pu , checkInstructionToEndpointRelation getInstrMap getEpMap $ process pu , checkCadToFunctionRelation getCadFunctions getCadSteps $ process pu ] --- every function should be binded to CAD step -- at the moment check LoopBegin/End checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels where @@ -89,28 +94,44 @@ checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels $ showLoop f ) $ M.toList cadFs - if length l > 1 - then Vertical h $ fst $ findJust (\(k, _) -> Vertical h k `elem` rels) l - else Vertical h $ fst $ head l + +-- FIX: S.isSubsetOf [] rels ; produces True +checkEndpointToIntermidiateRelation eps ifs pr = and $ S.isSubsetOf makeRelationList rels : [checkIfsEmpty, checkEpsEmpty] + where + checkIfsEmpty = not ((M.size eps > 0) && (M.size ifs == 0)) || error "Functions are empty. " + checkEpsEmpty = not ((M.size ifs > 0) && (M.size eps == 0)) || error "Endpoints are empty. " + rels = S.fromList $ filter isVertical $ relations pr + findRel (h, l) = + map (uncurry Vertical) $ + case find (\(k, _) -> Vertical h k `elem` rels) l of + Just res -> [(h, fst res)] + Nothing -> findRelReverse (h, l) + findRelReverse (h, l) = + case find (\(k, _) -> Vertical k h `elem` rels) l of + Just res -> [(fst res, h)] + Nothing -> error $ "Can't find Endpoint for Function with pID: " <> show [h] makeRelationList = S.fromList $ concatMap ( \(h, f) -> - concatMap - ( \v -> [findRel (h, eps M.! v)] - ) - $ variables f + concat $ + concatMap + ( \v -> [findRel (h, eps M.! v)] + ) + $ variables f ) $ M.toList ifs -checkInstructionToEndpointRelation ins eps pr = and makeRelationList +checkInstructionToEndpointRelation ins eps pr = and $ makeRelationList <> [checkInsEmpty, checkEpsEmpty] where rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr + checkInsEmpty = not ((M.size eps > 0) && (M.size ins == 0)) || error "Instructions are empty. " + checkEpsEmpty = not ((M.size ins > 0) && (M.size eps == 0)) || error "Endpoints are empty. " eps' = M.fromList $ concat $ M.elems eps makeRelationList = concatMap - ( \(r1, r2) -> case eps' M.!? r1 of - Just _ | (InstructionStep _) <- ins M.! r2 -> [True] + ( \(r1, r2) -> case eps' M.!? r1 of -- TODO could be two sided relation + Just _ | Just (InstructionStep _) <- ins M.!? r2 -> [True] _ -> [] ) rels diff --git a/src/NITTA/Model/ProcessorUnits/Broken.hs b/src/NITTA/Model/ProcessorUnits/Broken.hs index 2c9b7ee61..75a9d5014 100644 --- a/src/NITTA/Model/ProcessorUnits/Broken.hs +++ b/src/NITTA/Model/ProcessorUnits/Broken.hs @@ -154,11 +154,11 @@ instance (VarValTime v x t) => EndpointProblem (Broken v x t) v t where else scheduleEndpoint d ins endpoints <- res when (null sources') $ do - -- TODO: migrate to scheduleFunctionFinish - high <- scheduleFunction (a ... sup epAt) f - --if lostFunctionRelation - -- then return [] - -- else + -- TODO: migrate to scheduleFunctionFinish: unless lostFunctionRelation $ scheduleFunctionFinish low f (a ... sup epAt) + high <- + if lostFunctionRelation + then return [] + else scheduleFunction (a ... sup epAt) f let low = endpoints ++ currentWorkEndpoints unless lostFunctionRelation $ uncurry establishVerticalRelations (high, low) updateTick (sup epAt + 1) From 7d8144cd88e11dd23a68f3a8b4b7478af7b91036 Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Mon, 12 Apr 2021 17:15:51 +0300 Subject: [PATCH 30/49] Make data Relations more explicit (require for UI use) --- src/NITTA/Model/ProcessorUnits/Types.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index e2d494679..518d081aa 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -209,11 +209,11 @@ data Relation = -- |Vertical relationships (up and down). For example, the intermediate -- step (function execution) can be translated to a sequence of endpoint -- steps (receiving and sending variable), and process unit instructions. - Vertical ProcessStepID ProcessStepID + Vertical {vUp, vDown :: ProcessStepID} | -- |Horizontal relationships (on one level). For example, we bind the -- function and apply the refactoring. The binding step should be -- connected to refactoring steps, including new binding steps. - Horizontal ProcessStepID ProcessStepID + Horizontal {hPrev, hNext :: ProcessStepID} deriving (Show, Eq, Generic, Ord) isVertical Vertical{} = True From e7ad0961d6a0d1a8447d77779b3ae297cb2b5f1e Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 18 Apr 2021 21:05:17 +0300 Subject: [PATCH 31/49] trying to extract variable from Transport (Bus.hs) --- src/NITTA/Model/IntegrityCheck.hs | 9 +++++++++ src/NITTA/Model/Networks/Bus.hs | 1 + test/NITTA/Model/ProcessorUnits/Tests/Utils.hs | 6 +++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 449e10a72..22a6ea22b 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -19,8 +19,10 @@ import qualified Data.Map.Strict as M import qualified Data.Set as S import NITTA.Intermediate.Functions import NITTA.Intermediate.Types +import NITTA.Model.Networks.Bus (Instruction (Transport)) import NITTA.Model.ProcessorUnits import NITTA.Utils +import NITTA.Utils.ProcessDescription checkIntegrity pu = let getInterMap = @@ -52,6 +54,13 @@ checkIntegrity pu = _ -> [] ] + getTransportMap = + let filterTransport pu (InstructionStep ins) + | Just var@(Transport v src trg) <- castInstruction pu ins = Just v + | otherwise = Nothing + filterTransport _ _ = Nothing + in M.mapMaybe (filterTransport pu) getInstrMap + -- (pid, f) getCadFunctions = let filterCad (_, f) diff --git a/src/NITTA/Model/Networks/Bus.hs b/src/NITTA/Model/Networks/Bus.hs index 705c0ab59..e1734204b 100644 --- a/src/NITTA/Model/Networks/Bus.hs +++ b/src/NITTA/Model/Networks/Bus.hs @@ -25,6 +25,7 @@ For creating BusNetwork see 'NITTA.Model.Microarchitecture'. -} module NITTA.Model.Networks.Bus ( BusNetwork (..), + Instruction (..), Ports (..), IOPorts (..), bindedFunctions, diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index 58e40a4a4..e8f84b618 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -205,7 +205,7 @@ processAlgOnEndpointGen pu0 algGen' = do algSynthesisGen alg [] pu0 -- FIXME: support new synthesis/refactor style -data PUSynthesisTask r f e = BreakLoop r | Bind f | Transport e +data PUSynthesisTask r f e = BreakLoop r | Bind f | TransportST e algSynthesisGen fRemain fPassed pu = select tasksList where @@ -213,7 +213,7 @@ algSynthesisGen fRemain fPassed pu = select tasksList concat [ map BreakLoop $ breakLoopOptions pu , map Bind fRemain - , map Transport $ endpointOptions pu + , map TransportST $ endpointOptions pu ] select [] = return (pu, fPassed) @@ -225,7 +225,7 @@ algSynthesisGen fRemain fPassed pu = select tasksList (Left _err) -> algSynthesisGen fRemain' fPassed pu where fRemain' = delete f fRemain - taskPattern (Transport e) = do + taskPattern (TransportST e) = do d <- endpointOptionToDecision <$> endpointGen e let pu' = endpointDecision pu d algSynthesisGen fRemain fPassed pu' From 8568583d681bc91ae7f763613101fa3100b6e5bd Mon Sep 17 00:00:00 2001 From: artyom Date: Wed, 28 Apr 2021 20:53:46 +0300 Subject: [PATCH 32/49] feat_integrity: replaced transport to function relations (with cartesian mul) --- src/NITTA/Model/IntegrityCheck.hs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 22a6ea22b..fcb313471 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PartialTypeSignatures #-} @@ -17,6 +18,7 @@ module NITTA.Model.IntegrityCheck ( import Data.List (find) import qualified Data.Map.Strict as M import qualified Data.Set as S +import qualified Debug.Trace import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (Instruction (Transport)) @@ -56,7 +58,7 @@ checkIntegrity pu = getTransportMap = let filterTransport pu (InstructionStep ins) - | Just var@(Transport v src trg) <- castInstruction pu ins = Just v + | Just v <- castInstruction pu ins = Just v | otherwise = Nothing filterTransport _ _ = Nothing in M.mapMaybe (filterTransport pu) getInstrMap @@ -105,8 +107,9 @@ checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels $ M.toList cadFs -- FIX: S.isSubsetOf [] rels ; produces True -checkEndpointToIntermidiateRelation eps ifs pr = and $ S.isSubsetOf makeRelationList rels : [checkIfsEmpty, checkEpsEmpty] +checkEndpointToIntermidiateRelation eps ifs pr = and [checkRels, checkIfsEmpty, checkEpsEmpty] where + checkRels = any (`S.isSubsetOf` rels) $ makeRelationList2 eps ifs checkIfsEmpty = not ((M.size eps > 0) && (M.size ifs == 0)) || error "Functions are empty. " checkEpsEmpty = not ((M.size ifs > 0) && (M.size eps == 0)) || error "Endpoints are empty. " rels = S.fromList $ filter isVertical $ relations pr @@ -114,11 +117,7 @@ checkEndpointToIntermidiateRelation eps ifs pr = and $ S.isSubsetOf makeRelation map (uncurry Vertical) $ case find (\(k, _) -> Vertical h k `elem` rels) l of Just res -> [(h, fst res)] - Nothing -> findRelReverse (h, l) - findRelReverse (h, l) = - case find (\(k, _) -> Vertical k h `elem` rels) l of - Just res -> [(fst res, h)] - Nothing -> error $ "Can't find Endpoint for Function with pID: " <> show [h] + Nothing -> error $ "Can't find Endpoint for Function with pID: " <> show [h] makeRelationList = S.fromList $ concatMap @@ -131,6 +130,19 @@ checkEndpointToIntermidiateRelation eps ifs pr = and $ S.isSubsetOf makeRelation ) $ M.toList ifs +makeRelationList2 eps ifs = + let fuu = + map S.fromList $ + concatMap + ( \(h, f) -> + sequence $ + concatMap + ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] + ) + $ variables f + ) + $ M.toList ifs + in Debug.Trace.traceShow fuu fuu checkInstructionToEndpointRelation ins eps pr = and $ makeRelationList <> [checkInsEmpty, checkEpsEmpty] where rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr From 31fab6c303606ce3b03876bf76a5b4dde43f03e3 Mon Sep 17 00:00:00 2001 From: artyom Date: Wed, 28 Apr 2021 21:47:28 +0300 Subject: [PATCH 33/49] feat_integrity: test with Transport extraction --- src/NITTA/Model/IntegrityCheck.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index fcb313471..dab441aa7 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -57,8 +57,8 @@ checkIntegrity pu = ] getTransportMap = - let filterTransport pu (InstructionStep ins) - | Just v <- castInstruction pu ins = Just v + let filterTransport pu' (InstructionStep ins) + | Just (Transport v _ _) <- castInstruction pu' ins = Just v | otherwise = Nothing filterTransport _ _ = Nothing in M.mapMaybe (filterTransport pu) getInstrMap From 7b597468a809938880367c204f4c3df419cc3d45 Mon Sep 17 00:00:00 2001 From: artyom Date: Fri, 30 Apr 2021 15:18:50 +0300 Subject: [PATCH 34/49] integrity: added Eq to make reversed Relation equal. Added transport filter for PU --- src/NITTA/Model/IntegrityCheck.hs | 20 +++++++++++++++++++- src/NITTA/Model/ProcessorUnits/Types.hs | 8 +++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index dab441aa7..1bb641b36 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -1,7 +1,9 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE TypeFamilies #-} {- | Module : NITTA.Model.IntegrityCheck @@ -15,17 +17,24 @@ module NITTA.Model.IntegrityCheck ( checkIntegrity, ) where +import Data.Data import Data.List (find) import qualified Data.Map.Strict as M import qualified Data.Set as S import qualified Debug.Trace import NITTA.Intermediate.Functions import NITTA.Intermediate.Types -import NITTA.Model.Networks.Bus (Instruction (Transport)) +import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) import NITTA.Model.ProcessorUnits import NITTA.Utils import NITTA.Utils.ProcessDescription +class ProcessConsistent u where + checkProcessСonsistent :: u -> Either String () + +instance ProcessConsistent (BusNetwork pu v x t) where + checkProcessСonsistent pu = Left "cc" + checkIntegrity pu = let getInterMap = M.fromList @@ -90,6 +99,15 @@ checkIntegrity pu = , checkCadToFunctionRelation getCadFunctions getCadSteps $ process pu ] +getTransportMap2 pu = + let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) + getTransport _ = cast + filterTransport pu' (InstructionStep ins) + | Just (Transport v _ _) <- getTransport pu' ins = Just v + | otherwise = Nothing + filterTransport _ _ = Nothing + in M.mapMaybe (filterTransport pu) $ getInstrMap pu + -- at the moment check LoopBegin/End checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels where diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index 518d081aa..95449b7af 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -214,7 +214,7 @@ data Relation -- function and apply the refactoring. The binding step should be -- connected to refactoring steps, including new binding steps. Horizontal {hPrev, hNext :: ProcessStepID} - deriving (Show, Eq, Generic, Ord) + deriving (Show, Generic, Ord) isVertical Vertical{} = True isVertical _ = False @@ -224,6 +224,12 @@ isHorizontal _ = False instance ToJSON Relation +-- TODO: is it harmful? +instance Eq Relation where + (Vertical vUp vDown) == (Vertical vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown && vDown == vUp2 + (Horizontal vUp vDown) == (Horizontal vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown && vDown == vUp2 + _ == _ = False + whatsHappen t Process{steps} = filter (atSameTime t . pInterval) steps where atSameTime a ti = a `member` ti From 9df0e111264003965ae4bb1ee154cb3f7dc9725a Mon Sep 17 00:00:00 2001 From: artyom Date: Fri, 7 May 2021 23:48:30 +0300 Subject: [PATCH 35/49] feat_integrity: prototype (simple) for check Transport to Function --- src/NITTA/Model/IntegrityCheck.hs | 173 +++++++++++++++++++++--------- 1 file changed, 122 insertions(+), 51 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 1bb641b36..ed2719f79 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -13,13 +13,15 @@ License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} -module NITTA.Model.IntegrityCheck ( - checkIntegrity, -) where +module NITTA.Model.IntegrityCheck where +import Control.Monad import Data.Data -import Data.List (find) +import Data.Either +import Data.List (find, maximumBy) import qualified Data.Map.Strict as M +import Data.Maybe +import Data.Ord import qualified Data.Set as S import qualified Debug.Trace import NITTA.Intermediate.Functions @@ -33,9 +35,10 @@ class ProcessConsistent u where checkProcessСonsistent :: u -> Either String () instance ProcessConsistent (BusNetwork pu v x t) where - checkProcessСonsistent pu = Left "cc" + checkProcessСonsistent pu = Left "qc" checkIntegrity pu = + {-} let getInterMap = M.fromList [ (pID, f) @@ -65,13 +68,6 @@ checkIntegrity pu = _ -> [] ] - getTransportMap = - let filterTransport pu' (InstructionStep ins) - | Just (Transport v _ _) <- castInstruction pu' ins = Just v - | otherwise = Nothing - filterTransport _ _ = Nothing - in M.mapMaybe (filterTransport pu) getInstrMap - -- (pid, f) getCadFunctions = let filterCad (_, f) @@ -92,24 +88,19 @@ checkIntegrity pu = Just msg -> [msg] _ -> [] ] - in and + in -} + let handleLefts l = case partitionEithers l of + ([], _) -> True + (a, _) -> False -- error $ concat a + in handleLefts -- TODO: why so much calls(prints) in tests? - [ checkEndpointToIntermidiateRelation getEpMap getInterMap $ process pu - , checkInstructionToEndpointRelation getInstrMap getEpMap $ process pu - , checkCadToFunctionRelation getCadFunctions getCadSteps $ process pu + [ checkEndpointToIntermidiateRelation' (getEpMap pu) (getInterMap pu) pu + , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu + , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) $ process pu ] -getTransportMap2 pu = - let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) - getTransport _ = cast - filterTransport pu' (InstructionStep ins) - | Just (Transport v _ _) <- getTransport pu' ins = Just v - | otherwise = Nothing - filterTransport _ _ = Nothing - in M.mapMaybe (filterTransport pu) $ getInstrMap pu - -- at the moment check LoopBegin/End -checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels +checkCadToFunctionRelation cadFs cadSt pr = Right $ S.isSubsetOf makeCadVertical rels where rels = S.fromList $ filter isVertical $ relations pr showLoop f = "bind " <> show f @@ -124,31 +115,57 @@ checkCadToFunctionRelation cadFs cadSt pr = S.isSubsetOf makeCadVertical rels ) $ M.toList cadFs --- FIX: S.isSubsetOf [] rels ; produces True -checkEndpointToIntermidiateRelation eps ifs pr = and [checkRels, checkIfsEmpty, checkEpsEmpty] - where - checkRels = any (`S.isSubsetOf` rels) $ makeRelationList2 eps ifs - checkIfsEmpty = not ((M.size eps > 0) && (M.size ifs == 0)) || error "Functions are empty. " - checkEpsEmpty = not ((M.size ifs > 0) && (M.size eps == 0)) || error "Endpoints are empty. " - rels = S.fromList $ filter isVertical $ relations pr - findRel (h, l) = - map (uncurry Vertical) $ - case find (\(k, _) -> Vertical h k `elem` rels) l of - Just res -> [(h, fst res)] - Nothing -> error $ "Can't find Endpoint for Function with pID: " <> show [h] +-- checkEndpointToIntermidiateRelation a b c = undefined + +checkEndpointToIntermidiateRelation' eps ifs pu = + let res = any (`S.isSubsetOf` rels) genRels + genRels = makeRelationList eps ifs + rels = S.fromList $ filter isVertical $ relations $ process pu + biggestInter = getBiggestIntersection genRels rels + --checkIfsEmpty = not (M.size eps > 0 && M.size ifs == 0) || error "Functions are empty. " + checkIfsEmpty = (M.size eps > 0 && M.size ifs == 0) + --checkEpsEmpty = not (M.size ifs > 0 && M.size eps == 0) || error "Endpoints are empty. " + checkEpsEmpty = (M.size ifs > 0 && M.size eps == 0) + in if res && checkIfsEmpty && checkEpsEmpty + then Right res + else checkTransportToIntermidiateRelation pu ifs rels + +-- Lazy variant which don't take into account relation between @PU +-- TODO: add map with endpoints (as Source) to be sure that function is connected to endpoint after all +checkTransportToIntermidiateRelation pr ifs rels = + let res = any (`S.isSubsetOf` rels) makeRelationList + transM = getTransportMap pr makeRelationList = - S.fromList $ + map S.fromList $ concatMap ( \(h, f) -> - concat $ - concatMap - ( \v -> [findRel (h, eps M.! v)] - ) - $ variables f + concatMap + ( \v -> [[Vertical h $ fst $ transM M.! v]] + ) + $ variables f ) $ M.toList ifs + in if res + then Right res + else Left "Endpoint to Intermideate (function) not consistent" + +-- M.Map ProcessStepID (a, (ProcessStepID, Instruction (BusNetwork String a x1 t1))) +getTransportMap pu = + let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) + getTransport _ = cast + filterTransport pu' pid (InstructionStep ins) + | Just instr@(Transport v _ _) <- getTransport pu' ins = Just (v, (pid, instr)) + | otherwise = Nothing + filterTransport _ _ _ = Nothing + in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu + +-- WHAT IDEA? I forgot why i added it +getBiggestIntersection genRels rels = + map (maximumBy $ comparing S.size) [map (`S.intersection` rels) genRels] + +-- FIX: S.isSubsetOf [] rels ; produces True -makeRelationList2 eps ifs = +makeRelationList eps ifs = let fuu = map S.fromList $ concatMap @@ -160,12 +177,13 @@ makeRelationList2 eps ifs = $ variables f ) $ M.toList ifs - in Debug.Trace.traceShow fuu fuu -checkInstructionToEndpointRelation ins eps pr = and $ makeRelationList <> [checkInsEmpty, checkEpsEmpty] - where - rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr - checkInsEmpty = not ((M.size eps > 0) && (M.size ins == 0)) || error "Instructions are empty. " - checkEpsEmpty = not ((M.size ins > 0) && (M.size eps == 0)) || error "Endpoints are empty. " + in --in Debug.Trace.traceShow fuu fuu + fuu + +checkInstructionToEndpointRelation ins eps pr = + let rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr + checkInsEmpty = not (M.size eps > 0 && M.size ins == 0) || error "Instructions are empty. " + checkEpsEmpty = not (M.size ins > 0 && M.size eps == 0) || error "Endpoints are empty. " eps' = M.fromList $ concat $ M.elems eps makeRelationList = concatMap @@ -174,3 +192,56 @@ checkInstructionToEndpointRelation ins eps pr = and $ makeRelationList <> [check _ -> [] ) rels + in Right $ and $ makeRelationList <> [checkInsEmpty, checkEpsEmpty] + +getInterMap pu = + M.fromList + [ (pID, f) + | step@Step{pID} <- steps $ process pu + , isFB step + , f <- case getFunction step of + Just f -> [f] + _ -> [] + ] +getEpMap pu = + M.fromListWith (++) $ + concat + [ concatMap (\v -> [(v, [(pID, ep)])]) $ variables ep + | step@Step{pID} <- steps $ process pu + , isEndpoint step + , ep <- case getEndpoint step of + Just e -> [e] + _ -> [] + ] + +-- Contains instructions +getInstrMap pu = + M.fromList + [ (pID, instr) + | step@Step{pID} <- steps $ process pu + , isInstruction step + , instr <- case getInstruction step of + Just i -> [i] + _ -> [] + ] + +-- (pid, f) +getCadFunctions pu = + let filterCad (_, f) + | Just Loop{} <- castF f = True + | Just (LoopBegin Loop{} _) <- castF f = True + | Just (LoopEnd Loop{} _) <- castF f = True + | otherwise = False + in M.fromList $ filter filterCad $ M.toList $ getInterMap pu + +-- TODO: add Maybe? +-- (Loop (pid, f)) , where Loop is show instance +getCadSteps pu = + M.fromList $ + concat + [ concatMap (\l -> [(l, (pID, step))]) pDesc' + | step@Step{pID} <- steps $ process pu + , pDesc' <- case getCAD step of + Just msg -> [msg] + _ -> [] + ] From c801e297d5a2cf8d0c09e768aba060f535c60f1f Mon Sep 17 00:00:00 2001 From: artyom Date: Wed, 19 May 2021 20:11:29 +0300 Subject: [PATCH 36/49] fix_integrity: refactored most functions, fixed bug in Eq of Relation --- src/NITTA/Model/IntegrityCheck.hs | 176 +++++++++--------------- src/NITTA/Model/ProcessorUnits/Types.hs | 4 +- 2 files changed, 68 insertions(+), 112 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index ed2719f79..25f6507ff 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -7,7 +7,7 @@ {- | Module : NITTA.Model.IntegrityCheck -Description : Module for checking model description consistency +Description : Module for checking PU model description consistency Copyright : (c) Artyom Kostyuchik, 2021 License : BSD3 Maintainer : aleksandr.penskoi@gmail.com @@ -18,10 +18,8 @@ module NITTA.Model.IntegrityCheck where import Control.Monad import Data.Data import Data.Either -import Data.List (find, maximumBy) import qualified Data.Map.Strict as M import Data.Maybe -import Data.Ord import qualified Data.Set as S import qualified Debug.Trace import NITTA.Intermediate.Functions @@ -29,7 +27,6 @@ import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) import NITTA.Model.ProcessorUnits import NITTA.Utils -import NITTA.Utils.ProcessDescription class ProcessConsistent u where checkProcessСonsistent :: u -> Either String () @@ -38,116 +35,77 @@ instance ProcessConsistent (BusNetwork pu v x t) where checkProcessСonsistent pu = Left "qc" checkIntegrity pu = - {-} - let getInterMap = - M.fromList - [ (pID, f) - | step@Step{pID} <- steps $ process pu - , isFB step - , f <- case getFunction step of - Just f -> [f] - _ -> [] - ] - getEpMap = - M.fromListWith (++) $ - concat - [ concatMap (\v -> [(v, [(pID, ep)])]) $ variables ep - | step@Step{pID} <- steps $ process pu - , isEndpoint step - , ep <- case getEndpoint step of - Just e -> [e] - _ -> [] - ] - getInstrMap = - M.fromList - [ (pID, instr) - | step@Step{pID} <- steps $ process pu - , isInstruction step - , instr <- case getInstruction step of - Just i -> [i] - _ -> [] - ] - - -- (pid, f) - getCadFunctions = - let filterCad (_, f) - | Just Loop{} <- castF f = True - | Just (LoopBegin Loop{} _) <- castF f = True - | Just (LoopEnd Loop{} _) <- castF f = True - | otherwise = False - in M.fromList $ filter filterCad $ M.toList getInterMap - - -- TODO: add Maybe? - -- (Loop (pid, f)) , where Loop is show instance - getCadSteps = - M.fromList $ - concat - [ concatMap (\l -> [(l, (pID, step))]) pDesc' - | step@Step{pID} <- steps $ process pu - , pDesc' <- case getCAD step of - Just msg -> [msg] - _ -> [] - ] - in -} let handleLefts l = case partitionEithers l of ([], _) -> True - (a, _) -> False -- error $ concat a + -- (a, _) -> Debug.Trace.traceShow (concat a) False + (a, _) -> False in handleLefts -- TODO: why so much calls(prints) in tests? [ checkEndpointToIntermidiateRelation' (getEpMap pu) (getInterMap pu) pu , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu - , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) $ process pu + , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu ] -- at the moment check LoopBegin/End -checkCadToFunctionRelation cadFs cadSt pr = Right $ S.isSubsetOf makeCadVertical rels - where - rels = S.fromList $ filter isVertical $ relations pr +checkCadToFunctionRelation cadFs cadSt pu = + let consistent = S.isSubsetOf makeCadVertical rels + rels = S.fromList $ filter isVertical $ relations $ process pu showLoop f = "bind " <> show f makeCadVertical = S.fromList $ concatMap ( \(h, f) -> concatMap - ( \v -> [uncurry Vertical (h, fst $ cadSt M.! v)] + ( \v -> [uncurry Vertical (fst $ cadSt M.! v, h)] ) $ showLoop f ) $ M.toList cadFs - --- checkEndpointToIntermidiateRelation a b c = undefined + in if consistent + then Right True + else Left $ "CAD functions not consistent. excess:" <> show (S.difference makeCadVertical rels) <> " act: " <> show (process pu) checkEndpointToIntermidiateRelation' eps ifs pu = - let res = any (`S.isSubsetOf` rels) genRels - genRels = makeRelationList eps ifs + let genRels = makeRelationList eps ifs rels = S.fromList $ filter isVertical $ relations $ process pu - biggestInter = getBiggestIntersection genRels rels - --checkIfsEmpty = not (M.size eps > 0 && M.size ifs == 0) || error "Functions are empty. " - checkIfsEmpty = (M.size eps > 0 && M.size ifs == 0) - --checkEpsEmpty = not (M.size ifs > 0 && M.size eps == 0) || error "Endpoints are empty. " - checkEpsEmpty = (M.size ifs > 0 && M.size eps == 0) - in if res && checkIfsEmpty && checkEpsEmpty - then Right res - else checkTransportToIntermidiateRelation pu ifs rels + checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 + checkEpsEmpty = M.size ifs > 0 && M.size eps == 0 + in do + when checkIfsEmpty $ Left "functions are empty" + when checkEpsEmpty $ Left "eps are empty" + if any (`S.isSubsetOf` rels) genRels + then Right True + else checkTransportToIntermidiateRelation pu ifs rels eps -- Lazy variant which don't take into account relation between @PU -- TODO: add map with endpoints (as Source) to be sure that function is connected to endpoint after all -checkTransportToIntermidiateRelation pr ifs rels = - let res = any (`S.isSubsetOf` rels) makeRelationList - transM = getTransportMap pr +checkTransportToIntermidiateRelation pu ifs rels eps = + -- TODO we don't know did we found relation for all variables in function + let transM = getTransportMap pu + -- TODO: add smarter error handling + lookup v = fromMaybe (showErr v) $ transM M.!? v makeRelationList = map S.fromList $ concatMap ( \(h, f) -> concatMap - ( \v -> [[Vertical h $ fst $ transM M.! v]] + ( \v -> [[Vertical h $ fst $ lookup v]] ) $ variables f ) $ M.toList ifs - in if res - then Right res - else Left "Endpoint to Intermideate (function) not consistent" + showErr v = + error $ + show " variable is not present: " <> show v <> " \n" <> show (process pu) + <> "\nifs: " + <> show ifs + <> "\neps: " + <> show (length eps) + <> "\nrels: " + <> show rels + in if any (`S.isSubsetOf` rels) makeRelationList + then Right True + else Left "Endpoint and Transport to Intermideate (function) not consistent" -- M.Map ProcessStepID (a, (ProcessStepID, Instruction (BusNetwork String a x1 t1))) getTransportMap pu = @@ -159,40 +117,37 @@ getTransportMap pu = filterTransport _ _ _ = Nothing in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu --- WHAT IDEA? I forgot why i added it -getBiggestIntersection genRels rels = - map (maximumBy $ comparing S.size) [map (`S.intersection` rels) genRels] - --- FIX: S.isSubsetOf [] rels ; produces True - makeRelationList eps ifs = - let fuu = - map S.fromList $ - concatMap - ( \(h, f) -> - sequence $ - concatMap - ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] - ) - $ variables f - ) - $ M.toList ifs - in --in Debug.Trace.traceShow fuu fuu - fuu + map S.fromList $ + concatMap + ( \(h, f) -> + sequence $ + concatMap + ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] + ) + $ variables f + ) + $ M.toList ifs checkInstructionToEndpointRelation ins eps pr = - let rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr - checkInsEmpty = not (M.size eps > 0 && M.size ins == 0) || error "Instructions are empty. " - checkEpsEmpty = not (M.size ins > 0 && M.size eps == 0) || error "Endpoints are empty. " + let checkInsEmpty = M.size eps > 0 && M.size ins == 0 + checkEpsEmpty = M.size ins > 0 && M.size eps == 0 eps' = M.fromList $ concat $ M.elems eps - makeRelationList = - concatMap - ( \(r1, r2) -> case eps' M.!? r1 of -- TODO could be two sided relation - Just _ | Just (InstructionStep _) <- ins M.!? r2 -> [True] - _ -> [] - ) - rels - in Right $ and $ makeRelationList <> [checkInsEmpty, checkEpsEmpty] + rels = S.fromList $ map (\(Vertical r1 r2) -> (r1, r2)) $ filter isVertical $ relations pr + consistent = + and $ + concatMap + ( \(r1, r2) -> case eps' M.!? r1 of -- TODO could be two sided relation + Just _ | Just (InstructionStep _) <- ins M.!? r2 -> [True] + _ -> [] + ) + rels + in do + when checkInsEmpty $ Left "instructions are empty" + when checkEpsEmpty $ Left "enpoints are empty" + if consistent + then Right True + else Left "Instruction to Endpoint not consistent" getInterMap pu = M.fromList @@ -203,6 +158,7 @@ getInterMap pu = Just f -> [f] _ -> [] ] + getEpMap pu = M.fromListWith (++) $ concat diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index 95449b7af..e05e6c143 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -226,8 +226,8 @@ instance ToJSON Relation -- TODO: is it harmful? instance Eq Relation where - (Vertical vUp vDown) == (Vertical vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown && vDown == vUp2 - (Horizontal vUp vDown) == (Horizontal vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown && vDown == vUp2 + (Vertical vUp vDown) == (Vertical vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown2 && vDown == vUp2 + (Horizontal vUp vDown) == (Horizontal vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown2 && vDown == vUp2 _ == _ = False whatsHappen t Process{steps} = filter (atSameTime t . pInterval) steps From 3c8e583edebaaa14df34eb43ef2964717a25c555 Mon Sep 17 00:00:00 2001 From: artyom Date: Wed, 19 May 2021 21:38:35 +0300 Subject: [PATCH 37/49] feat_edsl: returned default deriving Relation --- src/NITTA/Model/ProcessorUnits/Types.hs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/NITTA/Model/ProcessorUnits/Types.hs b/src/NITTA/Model/ProcessorUnits/Types.hs index e05e6c143..e353e9425 100644 --- a/src/NITTA/Model/ProcessorUnits/Types.hs +++ b/src/NITTA/Model/ProcessorUnits/Types.hs @@ -214,7 +214,7 @@ data Relation -- function and apply the refactoring. The binding step should be -- connected to refactoring steps, including new binding steps. Horizontal {hPrev, hNext :: ProcessStepID} - deriving (Show, Generic, Ord) + deriving (Show, Generic, Ord, Eq) isVertical Vertical{} = True isVertical _ = False @@ -224,12 +224,6 @@ isHorizontal _ = False instance ToJSON Relation --- TODO: is it harmful? -instance Eq Relation where - (Vertical vUp vDown) == (Vertical vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown2 && vDown == vUp2 - (Horizontal vUp vDown) == (Horizontal vUp2 vDown2) = vUp == vUp2 && vDown == vDown2 || vUp == vDown2 && vDown == vUp2 - _ == _ = False - whatsHappen t Process{steps} = filter (atSameTime t . pInterval) steps where atSameTime a ti = a `member` ti From c794ef4108d1d653fecf8c8ae554e51de5b53e74 Mon Sep 17 00:00:00 2001 From: artyom Date: Fri, 21 May 2021 09:17:37 +0300 Subject: [PATCH 38/49] fix_edsl: refactored CAD tests, now it not fails --- src/NITTA/Model/IntegrityCheck.hs | 94 ++++++++++++++++--------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 25f6507ff..f7eb47e7c 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -37,35 +37,16 @@ instance ProcessConsistent (BusNetwork pu v x t) where checkIntegrity pu = let handleLefts l = case partitionEithers l of ([], _) -> True - -- (a, _) -> Debug.Trace.traceShow (concat a) False - (a, _) -> False - in handleLefts + (a, _) -> Debug.Trace.traceShow (concat a) False + in -- (a, _) -> False + handleLefts -- TODO: why so much calls(prints) in tests? - [ checkEndpointToIntermidiateRelation' (getEpMap pu) (getInterMap pu) pu + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu ] --- at the moment check LoopBegin/End -checkCadToFunctionRelation cadFs cadSt pu = - let consistent = S.isSubsetOf makeCadVertical rels - rels = S.fromList $ filter isVertical $ relations $ process pu - showLoop f = "bind " <> show f - makeCadVertical = - S.fromList $ - concatMap - ( \(h, f) -> - concatMap - ( \v -> [uncurry Vertical (fst $ cadSt M.! v, h)] - ) - $ showLoop f - ) - $ M.toList cadFs - in if consistent - then Right True - else Left $ "CAD functions not consistent. excess:" <> show (S.difference makeCadVertical rels) <> " act: " <> show (process pu) - -checkEndpointToIntermidiateRelation' eps ifs pu = +checkEndpointToIntermidiateRelation eps ifs pu = let genRels = makeRelationList eps ifs rels = S.fromList $ filter isVertical $ relations $ process pu checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 @@ -107,16 +88,6 @@ checkTransportToIntermidiateRelation pu ifs rels eps = then Right True else Left "Endpoint and Transport to Intermideate (function) not consistent" --- M.Map ProcessStepID (a, (ProcessStepID, Instruction (BusNetwork String a x1 t1))) -getTransportMap pu = - let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) - getTransport _ = cast - filterTransport pu' pid (InstructionStep ins) - | Just instr@(Transport v _ _) <- getTransport pu' ins = Just (v, (pid, instr)) - | otherwise = Nothing - filterTransport _ _ _ = Nothing - in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu - makeRelationList eps ifs = map S.fromList $ concatMap @@ -149,6 +120,34 @@ checkInstructionToEndpointRelation ins eps pr = then Right True else Left "Instruction to Endpoint not consistent" +-- at the moment check LoopBegin/End +checkCadToFunctionRelation cadFs cadSt pu = + let consistent = S.isSubsetOf makeCadVertical rels + rels = S.fromList $ filter isVertical $ relations $ process pu + showLoop f = "bind " <> show f + makeCadVertical = + S.fromList $ + concatMap + ( \(h, f) -> + concatMap + ( \v -> [uncurry Vertical (cadSt M.! v, h)] + ) + [showLoop f] + ) + $ M.toList cadFs + in if consistent + then Right True + else + Left $ + "CAD functions not consistent. excess:" + <> show (S.difference makeCadVertical rels) + <> " act: " + <> show (process pu) + <> " \nfs: " + <> show cadFs + <> " \nst: " + <> show cadSt + getInterMap pu = M.fromList [ (pID, f) @@ -181,6 +180,16 @@ getInstrMap pu = _ -> [] ] +-- M.Map ProcessStepID (a, (ProcessStepID, Instruction (BusNetwork String a x1 t1))) +getTransportMap pu = + let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) + getTransport _ = cast + filterTransport pu' pid (InstructionStep ins) + | Just instr@(Transport v _ _) <- getTransport pu' ins = Just (v, (pid, instr)) + | otherwise = Nothing + filterTransport _ _ _ = Nothing + in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu + -- (pid, f) getCadFunctions pu = let filterCad (_, f) @@ -190,14 +199,11 @@ getCadFunctions pu = | otherwise = False in M.fromList $ filter filterCad $ M.toList $ getInterMap pu --- TODO: add Maybe? --- (Loop (pid, f)) , where Loop is show instance getCadSteps pu = - M.fromList $ - concat - [ concatMap (\l -> [(l, (pID, step))]) pDesc' - | step@Step{pID} <- steps $ process pu - , pDesc' <- case getCAD step of - Just msg -> [msg] - _ -> [] - ] + M.fromList + [ (pDesc', pID) + | step@Step{pID} <- steps $ process pu + , pDesc' <- case getCAD step of + Just msg -> [msg] + _ -> [] + ] From 04585255230fde3ee4697da206ae36b35779d50a Mon Sep 17 00:00:00 2001 From: artyom Date: Fri, 21 May 2021 20:11:17 +0300 Subject: [PATCH 39/49] fix_edsl: refactor before merge to original branch --- src/NITTA/Model/IntegrityCheck.hs | 47 +++++++++++-------- .../Model/ProcessorUnits/Broken/Tests.hs | 5 +- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index f7eb47e7c..c37c84409 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -36,10 +36,10 @@ instance ProcessConsistent (BusNetwork pu v x t) where checkIntegrity pu = let handleLefts l = case partitionEithers l of - ([], _) -> True - (a, _) -> Debug.Trace.traceShow (concat a) False - in -- (a, _) -> False - handleLefts + ([], _) -> Debug.Trace.traceShow "Success" True + -- (a, _) -> Debug.Trace.traceShow ("Err msg: " <> concat a) False + (a, _) -> False + in handleLefts -- TODO: why so much calls(prints) in tests? [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu @@ -47,14 +47,35 @@ checkIntegrity pu = ] checkEndpointToIntermidiateRelation eps ifs pu = - let genRels = makeRelationList eps ifs - rels = S.fromList $ filter isVertical $ relations $ process pu + let rels = S.fromList $ filter isVertical $ relations $ process pu checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 checkEpsEmpty = M.size ifs > 0 && M.size eps == 0 + makeRelationList = + map S.fromList $ + concatMap + ( \(h, f) -> + sequence $ + concatMap + ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] + ) + $ variables f + ) + $ M.toList ifs + print = + Debug.Trace.traceShow + ( "\neps: " + -- <> show eps + <> "\nifs: " + --- <> show ifs + <> "\nproc: " + <> show (process pu) + ) + True in do when checkIfsEmpty $ Left "functions are empty" when checkEpsEmpty $ Left "eps are empty" - if any (`S.isSubsetOf` rels) genRels + + if any (`S.isSubsetOf` rels) makeRelationList -- && print then Right True else checkTransportToIntermidiateRelation pu ifs rels eps @@ -88,18 +109,6 @@ checkTransportToIntermidiateRelation pu ifs rels eps = then Right True else Left "Endpoint and Transport to Intermideate (function) not consistent" -makeRelationList eps ifs = - map S.fromList $ - concatMap - ( \(h, f) -> - sequence $ - concatMap - ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] - ) - $ variables f - ) - $ M.toList ifs - checkInstructionToEndpointRelation ins eps pr = let checkInsEmpty = M.size eps > 0 && M.size ins == 0 checkEpsEmpty = M.size ins > 0 && M.size eps == 0 diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index 7dfc56ca0..85c313274 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -138,7 +138,10 @@ tests = , puCoSimProp "puCoSimProp relation positive test" u fsGen , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen - , expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + ] + , testGroup + "broken puCoSimTestCase" + [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua From 16361403f8eb2a6f542dc13e6c04a79f56ba4efc Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 23 May 2021 18:30:12 +0300 Subject: [PATCH 40/49] fix_integrity: fixed merge error --- src/NITTA/Utils.hs | 3 + .../NITTA/Model/ProcessorUnits/Tests/Utils.hs | 159 +++++------------- 2 files changed, 48 insertions(+), 114 deletions(-) diff --git a/src/NITTA/Utils.hs b/src/NITTA/Utils.hs index 640c4ff08..9331e4145 100644 --- a/src/NITTA/Utils.hs +++ b/src/NITTA/Utils.hs @@ -39,6 +39,7 @@ module NITTA.Utils ( stepsInterval, relatedEndpoints, isFB, + getFBs, isEndpoint, isInstruction, module NITTA.Utils.Base, @@ -115,6 +116,8 @@ isFB s = isJust $ getFB s getFB Step{pDesc} | FStep fb <- descent pDesc = Just fb getFB _ = Nothing +getFBs p = mapMaybe getFB $ sortOn stepStart $ steps p + isEndpoint ep = isJust $ getEndpoint ep getEndpoint Step{pDesc} | EndpointRoleStep role <- descent pDesc = Just role diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs index e8f84b618..f03ce1304 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Utils.hs @@ -18,78 +18,75 @@ Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} module NITTA.Model.ProcessorUnits.Tests.Utils ( - puCoSimTestCase, - nittaCoSimTestCase, - finitePUSynthesisProp, - puCoSimProp, + puCoSim, + naiveSynthesis, + isProcessComplete, + incompleteProcessMsg, algGen, + initialCycleCntxGen, + processAlgOnEndpointGen, + algSynthesisGen, ) where -import Control.Monad -import Data.Atomics.Counter (incrCounter) import Data.CallStack import Data.Default import Data.List (delete) import qualified Data.Map.Strict as M import Data.Set (elems, empty, fromList, intersection, union) -import qualified Data.String.Utils as S import qualified Data.Text as T -import NITTA.Intermediate.DataFlow import NITTA.Intermediate.Functions () import NITTA.Intermediate.Simulation import NITTA.Intermediate.Types -import NITTA.Model.IntegrityCheck -import NITTA.Model.Networks.Bus import NITTA.Model.Networks.Types import NITTA.Model.Problems hiding (Bind, BreakLoop) import NITTA.Model.ProcessorUnits import NITTA.Model.TargetSystem () -import NITTA.Model.Tests.Microarchitecture import NITTA.Project import qualified NITTA.Project as P -import NITTA.Synthesis import NITTA.Utils import System.Directory -import System.FilePath.Posix (joinPath) +import System.FilePath.Posix import Test.QuickCheck -import Test.QuickCheck.Monadic -import Test.Tasty (TestTree) -import Test.Tasty.HUnit (assertBool, assertFailure, testCase, (@?)) -import Test.Tasty.QuickCheck (testProperty) --- *Test cases - --- |Execute co-simulation test for the specific process unit -puCoSimTestCase :: +{- |Execute co-simulation test for the specific process unit +with or without "naive synthesis". +-} +puCoSim :: ( HasCallStack - , PUClasses (pu String x Int) String x Int - , WithFunctions (pu String x Int) (F String x) - , P.Testable (pu String x Int) String x - , DefaultX (pu String x Int) x + , PUClasses pu String x Int + , WithFunctions pu (F String x) + , P.Testable pu String x + , DefaultX pu x ) => String -> - pu String x Int -> + pu -> [(String, x)] -> [F String x] -> - TestTree -puCoSimTestCase name u cntxCycle alg = - testCase name $ do - wd <- getCurrentDirectory - let mname = toModuleName name - pTargetProjectPath = joinPath [wd, "gen", mname] - prj = - Project - { pName = T.pack mname - , pLibPath = "hdl" - , pTargetProjectPath - , pNittaPath = "." - , pUnit = naiveSynthesis alg u - , pUnitEnv = def - , pTestCntx = simulateAlg 5 (CycleCntx $ M.fromList cntxCycle) [] alg - , pTemplates = ["templates/Icarus"] - } - writeProject prj - (tbStatus <$> runTestbench prj) @? (name <> " in " <> pTargetProjectPath) + Bool -> + IO (TestbenchReport String x) +puCoSim name u cntxCycle alg needBind = do + pwd <- getCurrentDirectory + let mname = toModuleName name + pTargetProjectPath = "gen" mname + pInProjectNittaPath = "." + prj = + Project + { pName = T.pack mname + , pLibPath = "hdl" + , pTargetProjectPath + , pAbsTargetProjectPath = pwd pTargetProjectPath + , pInProjectNittaPath + , pAbsNittaPath = pwd pInProjectNittaPath pTargetProjectPath + , pUnit = + if needBind + then naiveSynthesis alg u + else u + , pUnitEnv = def + , pTestCntx = simulateAlg 5 (CycleCntx $ M.fromList cntxCycle) [] alg + , pTemplates = ["templates/Icarus"] + } + writeProject prj + runTestbench prj {- |Bind all functions to processor unit and synthesis process with endpoint decisions. @@ -101,40 +98,6 @@ naiveSynthesis alg u0 = naiveSynthesis' $ foldl (flip bind) u0 alg naiveSynthesis' $ endpointDecision u $ endpointOptionToDecision opt | otherwise = u --- |Execute co-simulation test for the specific microarchitecture and algorithm -nittaCoSimTestCase :: - ( HasCallStack - , Val x - , Integral x - ) => - String -> - BusNetwork String String x Int -> - [F String x] -> - TestTree -nittaCoSimTestCase n tMicroArch alg = - testCase n $ do - report <- - runTargetSynthesisWithUniqName - def - { tName = S.replace " " "_" n - , tMicroArch - , tDFG = fsToDataFlowGraph alg - } - case report of - Right report' -> assertBool "report with bad status" $ tbStatus report' - Left err -> assertFailure $ "can't get report: " ++ err - --- *Properties - --- |Is unit synthesis process complete (by function and variables). -finitePUSynthesisProp name pu0 fsGen = - testProperty name $ do - (pu, fs) <- processAlgOnEndpointGen pu0 fsGen - return $ - isProcessComplete pu fs - && null (endpointOptions pu) - && checkIntegrity pu - isProcessComplete pu fs = unionsMap variables fs == processedVars pu incompleteProcessMsg pu fs = @@ -144,38 +107,6 @@ incompleteProcessMsg pu fs = processedVars pu = unionsMap variables $ getEndpoints $ process pu -{- |A computational process of functional (Haskell) and logical (Verilog) -simulation should be identical for any correct algorithm. --} -puCoSimProp name pu0 fsGen = - testProperty name $ do - (pu, fs) <- processAlgOnEndpointGen pu0 fsGen - pTestCntx <- initialCycleCntxGen fs - return $ - monadicIO $ - run $ do - unless (isProcessComplete pu fs) $ - error $ "process is not complete: " <> incompleteProcessMsg pu fs - unless (checkIntegrity pu) $ - error "fail at integrity check" - i <- incrCounter 1 externalTestCntr - wd <- getCurrentDirectory - let pTargetProjectPath = joinPath [wd, "gen", toModuleName name <> "_" <> show i] - prj = - Project - { pName = T.pack $ toModuleName name - , pLibPath = "hdl" - , pTargetProjectPath - , pNittaPath = "." - , pUnit = pu - , pUnitEnv = def - , pTestCntx - , pTemplates = ["templates/Icarus"] - } - writeProject prj - res <- runTestbench prj - unless (tbStatus res) $ error $ "Fail CoSim in: " <> pTargetProjectPath - algGen fsGen = fmap avoidDupVariables $ listOf1 $ oneof fsGen where avoidDupVariables alg = @@ -205,7 +136,7 @@ processAlgOnEndpointGen pu0 algGen' = do algSynthesisGen alg [] pu0 -- FIXME: support new synthesis/refactor style -data PUSynthesisTask r f e = BreakLoop r | Bind f | TransportST e +data PUSynthesisTask r f e = BreakLoop r | Bind f | Transport e algSynthesisGen fRemain fPassed pu = select tasksList where @@ -213,7 +144,7 @@ algSynthesisGen fRemain fPassed pu = select tasksList concat [ map BreakLoop $ breakLoopOptions pu , map Bind fRemain - , map TransportST $ endpointOptions pu + , map Transport $ endpointOptions pu ] select [] = return (pu, fPassed) @@ -225,7 +156,7 @@ algSynthesisGen fRemain fPassed pu = select tasksList (Left _err) -> algSynthesisGen fRemain' fPassed pu where fRemain' = delete f fRemain - taskPattern (TransportST e) = do + taskPattern (Transport e) = do d <- endpointOptionToDecision <$> endpointGen e let pu' = endpointDecision pu d algSynthesisGen fRemain fPassed pu' From bef5a11936dc6585ad3939b023669350cbeaf9f6 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 23 May 2021 18:33:10 +0300 Subject: [PATCH 41/49] refactor_edsl: added error print when element in not found in map. Added templates for future typeclass. --- src/NITTA/Model/IntegrityCheck.hs | 77 ++++++++++++++----------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index c37c84409..59fc153a7 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -21,22 +21,32 @@ import Data.Either import qualified Data.Map.Strict as M import Data.Maybe import qualified Data.Set as S +import Data.String (IsString) +import Data.String.ToString (ToString) import qualified Debug.Trace import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) import NITTA.Model.ProcessorUnits +import NITTA.Model.TargetSystem import NITTA.Utils class ProcessConsistent u where - checkProcessСonsistent :: u -> Either String () + -- checkProcessСonsistent :: u -> Either String () + checkProcessСonsistent :: u -> Bool -instance ProcessConsistent (BusNetwork pu v x t) where - checkProcessСonsistent pu = Left "qc" +instance {-# OVERLAPS #-} (ProcessorUnit u v x t) => ProcessConsistent (TargetSystem u tag v x t) where + -- checkProcessСonsistent pu = Left "ssss" + checkProcessСonsistent pu = False + +instance (ProcessorUnit u v x t, Typeable u, Ord u, ToString u, IsString u) => ProcessConsistent (BusNetwork u v x t) where + -- checkProcessСonsistent pu = Left "qc" + checkProcessСonsistent pu = checkIntegrity pu checkIntegrity pu = let handleLefts l = case partitionEithers l of - ([], _) -> Debug.Trace.traceShow "Success" True + ([], _) -> True + -- ([], _) -> Debug.Trace.traceShow "Success" True -- (a, _) -> Debug.Trace.traceShow ("Err msg: " <> concat a) False (a, _) -> False in handleLefts @@ -50,61 +60,43 @@ checkEndpointToIntermidiateRelation eps ifs pu = let rels = S.fromList $ filter isVertical $ relations $ process pu checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 checkEpsEmpty = M.size ifs > 0 && M.size eps == 0 + lookup' v = fromMaybe (showError "Endpoint to Intermidiate" "enpoint" v) $ eps M.!? v makeRelationList = map S.fromList $ concatMap ( \(h, f) -> sequence $ concatMap - ( \v -> [[Vertical h $ fst p | p <- eps M.! v]] + ( \v -> [[Vertical h $ fst p | p <- lookup' v]] ) $ variables f ) $ M.toList ifs - print = - Debug.Trace.traceShow - ( "\neps: " - -- <> show eps - <> "\nifs: " - --- <> show ifs - <> "\nproc: " - <> show (process pu) - ) - True in do when checkIfsEmpty $ Left "functions are empty" when checkEpsEmpty $ Left "eps are empty" if any (`S.isSubsetOf` rels) makeRelationList -- && print then Right True - else checkTransportToIntermidiateRelation pu ifs rels eps + else checkTransportToIntermidiateRelation pu ifs rels -- Lazy variant which don't take into account relation between @PU -- TODO: add map with endpoints (as Source) to be sure that function is connected to endpoint after all -checkTransportToIntermidiateRelation pu ifs rels eps = +checkTransportToIntermidiateRelation pu ifs rels = -- TODO we don't know did we found relation for all variables in function - let transM = getTransportMap pu + let transMap = getTransportMap pu -- TODO: add smarter error handling - lookup v = fromMaybe (showErr v) $ transM M.!? v + lookup' v = fromMaybe (showError "Transport to Intermidiate" "transport" v) $ transMap M.!? v makeRelationList = map S.fromList $ concatMap ( \(h, f) -> concatMap - ( \v -> [[Vertical h $ fst $ lookup v]] + ( \v -> [[Vertical h $ fst $ lookup' v]] ) $ variables f ) $ M.toList ifs - showErr v = - error $ - show " variable is not present: " <> show v <> " \n" <> show (process pu) - <> "\nifs: " - <> show ifs - <> "\neps: " - <> show (length eps) - <> "\nrels: " - <> show rels in if any (`S.isSubsetOf` rels) makeRelationList then Right True else Left "Endpoint and Transport to Intermideate (function) not consistent" @@ -117,7 +109,7 @@ checkInstructionToEndpointRelation ins eps pr = consistent = and $ concatMap - ( \(r1, r2) -> case eps' M.!? r1 of -- TODO could be two sided relation + ( \(r1, r2) -> case eps' M.!? r1 of Just _ | Just (InstructionStep _) <- ins M.!? r2 -> [True] _ -> [] ) @@ -130,32 +122,24 @@ checkInstructionToEndpointRelation ins eps pr = else Left "Instruction to Endpoint not consistent" -- at the moment check LoopBegin/End -checkCadToFunctionRelation cadFs cadSt pu = +checkCadToFunctionRelation cadFs cadSteps pu = let consistent = S.isSubsetOf makeCadVertical rels rels = S.fromList $ filter isVertical $ relations $ process pu showLoop f = "bind " <> show f + lookup' v = fromMaybe (showError "CAD" "steps" v) $ cadSteps M.!? v makeCadVertical = S.fromList $ concatMap ( \(h, f) -> concatMap - ( \v -> [uncurry Vertical (cadSt M.! v, h)] + ( \v -> [uncurry Vertical (lookup' v, h)] ) [showLoop f] ) $ M.toList cadFs in if consistent then Right True - else - Left $ - "CAD functions not consistent. excess:" - <> show (S.difference makeCadVertical rels) - <> " act: " - <> show (process pu) - <> " \nfs: " - <> show cadFs - <> " \nst: " - <> show cadSt + else Left $ "CAD functions not consistent. Excess:" <> show (S.difference makeCadVertical rels) getInterMap pu = M.fromList @@ -216,3 +200,12 @@ getCadSteps pu = Just msg -> [msg] _ -> [] ] + +showError name mapName v = + error $ + name + <> " relations contain error: " + <> show v + <> " is not present in " + <> mapName + <> " map." From 0ce1c3c14be51f77843ef1848b0bbdd99f06c85a Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 23 May 2021 19:43:22 +0300 Subject: [PATCH 42/49] refactor_integrity: added implementation to ProcessConsistent typeclass. --- src/NITTA/Model/IntegrityCheck.hs | 61 ++++++++++++++++--------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 59fc153a7..6384eb64f 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -4,6 +4,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} {- | Module : NITTA.Model.IntegrityCheck @@ -28,33 +29,39 @@ import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) import NITTA.Model.ProcessorUnits -import NITTA.Model.TargetSystem import NITTA.Utils class ProcessConsistent u where - -- checkProcessСonsistent :: u -> Either String () - checkProcessСonsistent :: u -> Bool + checkProcessСonsistent :: u -> Either String () -instance {-# OVERLAPS #-} (ProcessorUnit u v x t) => ProcessConsistent (TargetSystem u tag v x t) where - -- checkProcessСonsistent pu = Left "ssss" - checkProcessСonsistent pu = False +instance (Typeable t, Typeable x, ProcessorUnit (pu v x t) v x2 t2) => ProcessConsistent (pu v x t) where + checkProcessСonsistent pu = + let consistent = checkIntegrity' pu + in if any isLeft consistent + then Left $ concat $ lefts consistent + else Right () instance (ProcessorUnit u v x t, Typeable u, Ord u, ToString u, IsString u) => ProcessConsistent (BusNetwork u v x t) where - -- checkProcessСonsistent pu = Left "qc" - checkProcessСonsistent pu = checkIntegrity pu - -checkIntegrity pu = - let handleLefts l = case partitionEithers l of - ([], _) -> True - -- ([], _) -> Debug.Trace.traceShow "Success" True - -- (a, _) -> Debug.Trace.traceShow ("Err msg: " <> concat a) False - (a, _) -> False - in handleLefts - -- TODO: why so much calls(prints) in tests? - [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu - , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu - , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu - ] + checkProcessСonsistent pu = + let consistent = checkIntegrity' pu + in if any isLeft consistent + then Left $ concat $ lefts consistent + else Right () + +handleLefts l = case partitionEithers l of + ([], _) -> True + -- ([], _) -> Debug.Trace.traceShow "Success" True + -- (a, _) -> Debug.Trace.traceShow ("Err msg: " <> concat a) False + (a, _) -> False + +checkIntegrity pu = handleLefts $ checkIntegrity' pu + +checkIntegrity' pu = + -- TODO: why so much calls(prints) in tests? + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu + , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu + , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu + ] checkEndpointToIntermidiateRelation eps ifs pu = let rels = S.fromList $ filter isVertical $ relations $ process pu @@ -75,17 +82,14 @@ checkEndpointToIntermidiateRelation eps ifs pu = in do when checkIfsEmpty $ Left "functions are empty" when checkEpsEmpty $ Left "eps are empty" - - if any (`S.isSubsetOf` rels) makeRelationList -- && print + if any (`S.isSubsetOf` rels) makeRelationList then Right True else checkTransportToIntermidiateRelation pu ifs rels --- Lazy variant which don't take into account relation between @PU -- TODO: add map with endpoints (as Source) to be sure that function is connected to endpoint after all +-- it means: Endpoint (Source) -> Transport -> Function checkTransportToIntermidiateRelation pu ifs rels = - -- TODO we don't know did we found relation for all variables in function let transMap = getTransportMap pu - -- TODO: add smarter error handling lookup' v = fromMaybe (showError "Transport to Intermidiate" "transport" v) $ transMap M.!? v makeRelationList = map S.fromList $ @@ -121,7 +125,7 @@ checkInstructionToEndpointRelation ins eps pr = then Right True else Left "Instruction to Endpoint not consistent" --- at the moment check LoopBegin/End +-- now it checks LoopBegin/End checkCadToFunctionRelation cadFs cadSteps pu = let consistent = S.isSubsetOf makeCadVertical rels rels = S.fromList $ filter isVertical $ relations $ process pu @@ -162,7 +166,6 @@ getEpMap pu = _ -> [] ] --- Contains instructions getInstrMap pu = M.fromList [ (pID, instr) @@ -173,7 +176,6 @@ getInstrMap pu = _ -> [] ] --- M.Map ProcessStepID (a, (ProcessStepID, Instruction (BusNetwork String a x1 t1))) getTransportMap pu = let getTransport :: (Typeable a, Typeable v, Typeable x, Typeable t) => pu v x t -> a -> Maybe (Instruction (BusNetwork String v x t)) getTransport _ = cast @@ -183,7 +185,6 @@ getTransportMap pu = filterTransport _ _ _ = Nothing in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu --- (pid, f) getCadFunctions pu = let filterCad (_, f) | Just Loop{} <- castF f = True From 02bf39cf792912b74d89071a8f8dd92e19125c12 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 23 May 2021 20:52:07 +0300 Subject: [PATCH 43/49] refactor_integrity: commented negative tests. Modified existing tests to be able to test integrity. --- src/NITTA/Model/IntegrityCheck.hs | 10 +++------- src/NITTA/Synthesis/Explore.hs | 3 ++- test/NITTA/Model/ProcessorUnits/Broken/Tests.hs | 16 +++++++++------- .../Model/ProcessorUnits/Tests/Providers.hs | 13 ++++++++++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 6384eb64f..9198de134 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -48,16 +48,12 @@ instance (ProcessorUnit u v x t, Typeable u, Ord u, ToString u, IsString u) => P then Left $ concat $ lefts consistent else Right () -handleLefts l = case partitionEithers l of - ([], _) -> True - -- ([], _) -> Debug.Trace.traceShow "Success" True - -- (a, _) -> Debug.Trace.traceShow ("Err msg: " <> concat a) False - (a, _) -> False +handleLefts pu l = + not (any isLeft l) || error (concat (lefts l) <> show (process pu)) -checkIntegrity pu = handleLefts $ checkIntegrity' pu +checkIntegrity pu = handleLefts pu $ checkIntegrity' pu checkIntegrity' pu = - -- TODO: why so much calls(prints) in tests? [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu diff --git a/src/NITTA/Synthesis/Explore.hs b/src/NITTA/Synthesis/Explore.hs index 31e0d55c9..d26d95814 100644 --- a/src/NITTA/Synthesis/Explore.hs +++ b/src/NITTA/Synthesis/Explore.hs @@ -119,8 +119,9 @@ isLeaf , sResolveDeadlockOptions = [] , sOptimizeAccumOptions = [] , sConstantFoldingOptions = [] + , sTarget } - } = True + } = checkIntegrity $ mUnit sTarget isLeaf _ = False isComplete = isSynthesisComplete . sTarget . sState diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index 85c313274..d47b20393 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -139,13 +139,15 @@ tests = , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen ] - , testGroup - "broken puCoSimTestCase" - [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] - , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] - , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg - , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua - ] + {- + , testGroup + "broken puCoSimTestCase" + [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg + , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua + ] + -} ] where u = def :: Broken String Int Int diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs b/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs index 0ebcc8198..21cf7a000 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs @@ -34,10 +34,12 @@ import Control.Monad import Data.CallStack import Data.Data import Data.Default +import Data.Either (fromLeft, isLeft) import qualified Data.Text as T import NITTA.Intermediate.Functions import NITTA.Intermediate.Tests.Functions () import NITTA.Intermediate.Types +import NITTA.Model.IntegrityCheck import NITTA.Model.Networks.Types import NITTA.Model.Problems hiding (Bind, BreakLoop) import NITTA.Model.ProcessorUnits @@ -81,9 +83,12 @@ puCoSimTestCase name u cntxCycle alg = finitePUSynthesisProp name pu0 fsGen = testProperty name $ do (pu, fs) <- processAlgOnEndpointGen pu0 fsGen - return $ - isProcessComplete pu fs - && null (endpointOptions pu) + case checkProcessСonsistent pu of + Left msg -> error msg + Right _ -> + return $ + isProcessComplete pu fs + && null (endpointOptions pu) {- |A computational process of functional (Haskell) and logical (Verilog) simulation should be identical for any correct algorithm. @@ -97,6 +102,8 @@ puCoSimProp name pu0 fsGen = run $ do unless (isProcessComplete pu fs) $ error $ "process is not complete: " <> incompleteProcessMsg pu fs + when (isLeft $ checkProcessСonsistent pu) $ + error $ fromLeft "Consistency check error" $ checkProcessСonsistent pu i <- incrCounter 1 externalTestCntr pwd <- getCurrentDirectory let pTargetProjectPath = "gen" (toModuleName name <> "_" <> show i) From 63a7eaa61278738e191aa90ce7b15b35d4f0f97e Mon Sep 17 00:00:00 2001 From: artyom Date: Sat, 29 May 2021 23:03:05 +0300 Subject: [PATCH 44/49] feat_integrity: added assertConsistency to DSL --- test/NITTA/Model/ProcessorUnits/Tests/DSL.hs | 10 ++++++++++ test/NITTA/Model/ProcessorUnits/Tests/Providers.hs | 1 + 2 files changed, 11 insertions(+) diff --git a/test/NITTA/Model/ProcessorUnits/Tests/DSL.hs b/test/NITTA/Model/ProcessorUnits/Tests/DSL.hs index 80cd81b12..f8b625236 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/DSL.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/DSL.hs @@ -118,6 +118,7 @@ module NITTA.Model.ProcessorUnits.Tests.DSL ( assertBindFullness, assertCoSimulation, assertSynthesisDone, + assertConsistency, assertEndpoint, assertAllEndpointRoles, assertLocks, @@ -132,9 +133,11 @@ module NITTA.Model.ProcessorUnits.Tests.DSL ( import Control.Monad.Identity import Control.Monad.State.Lazy import Data.CallStack +import Data.Either import Data.List (find) import qualified Data.Set as S import NITTA.Intermediate.Types +import NITTA.Model.IntegrityCheck import NITTA.Model.Networks.Types (PUClasses) import NITTA.Model.Problems import NITTA.Model.ProcessorUnits @@ -317,6 +320,13 @@ assertSynthesisDone = do unless (isProcessComplete unit functs && null (endpointOptions unit)) $ lift $ assertFailure $ testName <> " Process is not done: " <> incompleteProcessMsg unit functs +assertConsistency :: ProcessConsistent pu => DSLStatement pu v x t () +assertConsistency = do + UnitTestState{unit, testName} <- get + let res = checkProcessСonsistent unit + when (isLeft res) $ + lift $ assertFailure $ testName <> " Process is not consistent: " <> show (fromLeft "no msg!" res) + assertLocks :: (Locks pu v) => [Lock v] -> DSLStatement pu v x t () assertLocks expectLocks = do UnitTestState{unit} <- get diff --git a/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs b/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs index 21cf7a000..4bf47882c 100644 --- a/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs +++ b/test/NITTA/Model/ProcessorUnits/Tests/Providers.hs @@ -75,6 +75,7 @@ puCoSimTestCase name u cntxCycle alg = unitTestCase name u $ do assignsNaive alg cntxCycle decideNaiveSynthesis + assertConsistency assertCoSimulation -- *Properties From a062f690189c177737497de04e5232b4c414b851 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 30 May 2021 00:12:16 +0300 Subject: [PATCH 45/49] fix_integrity: removed checkIntegrity, replaced order of some functions, added detailed error (debug purpose). Rearranged tests in broken. --- src/NITTA/Model/IntegrityCheck.hs | 82 ++++++++++--------- .../Model/ProcessorUnits/Broken/Tests.hs | 39 ++++----- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 9198de134..1cd054466 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -14,7 +14,9 @@ License : BSD3 Maintainer : aleksandr.penskoi@gmail.com Stability : experimental -} -module NITTA.Model.IntegrityCheck where +module NITTA.Model.IntegrityCheck ( + ProcessConsistent (..), +) where import Control.Monad import Data.Data @@ -24,7 +26,6 @@ import Data.Maybe import qualified Data.Set as S import Data.String (IsString) import Data.String.ToString (ToString) -import qualified Debug.Trace import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) @@ -34,36 +35,34 @@ import NITTA.Utils class ProcessConsistent u where checkProcessСonsistent :: u -> Either String () -instance (Typeable t, Typeable x, ProcessorUnit (pu v x t) v x2 t2) => ProcessConsistent (pu v x t) where +instance (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessConsistent (pu v x t) where checkProcessСonsistent pu = - let consistent = checkIntegrity' pu - in if any isLeft consistent - then Left $ concat $ lefts consistent - else Right () - -instance (ProcessorUnit u v x t, Typeable u, Ord u, ToString u, IsString u) => ProcessConsistent (BusNetwork u v x t) where + let isConsistent = + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu + , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu + , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu + ] + in checkResult isConsistent + +instance (ProcessorUnit u v x t, Typeable u, IsString u, ToString u, Ord u) => ProcessConsistent (BusNetwork u v x t) where checkProcessСonsistent pu = - let consistent = checkIntegrity' pu - in if any isLeft consistent - then Left $ concat $ lefts consistent - else Right () - -handleLefts pu l = - not (any isLeft l) || error (concat (lefts l) <> show (process pu)) - -checkIntegrity pu = handleLefts pu $ checkIntegrity' pu - -checkIntegrity' pu = - [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) pu - , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu - , checkCadToFunctionRelation (getCadFunctions pu) (getCadSteps pu) pu - ] - -checkEndpointToIntermidiateRelation eps ifs pu = - let rels = S.fromList $ filter isVertical $ relations $ process pu - checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 + let isConsistent = + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu + , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu + , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu + ] + in checkResult isConsistent + +checkResult res = + if any isLeft res + then Left $ concat $ lefts res + else Right () + +checkEndpointToIntermidiateRelation eps ifs trans pu = + let checkIfsEmpty = M.size eps > 0 && M.size ifs == 0 checkEpsEmpty = M.size ifs > 0 && M.size eps == 0 - lookup' v = fromMaybe (showError "Endpoint to Intermidiate" "enpoint" v) $ eps M.!? v + rels = S.fromList $ filter isVertical $ relations $ process pu + lookup' v = fromMaybe (showError "Endpoint to Intermidiate" "enpoint" v pu) $ eps M.!? v makeRelationList = map S.fromList $ concatMap @@ -76,17 +75,19 @@ checkEndpointToIntermidiateRelation eps ifs pu = ) $ M.toList ifs in do - when checkIfsEmpty $ Left "functions are empty" - when checkEpsEmpty $ Left "eps are empty" + when checkEpsEmpty $ + Left "endpoints are empty" + when checkIfsEmpty $ + Left "functions are empty" if any (`S.isSubsetOf` rels) makeRelationList then Right True - else checkTransportToIntermidiateRelation pu ifs rels + else checkTransportToIntermidiateRelation ifs rels trans pu -- TODO: add map with endpoints (as Source) to be sure that function is connected to endpoint after all -- it means: Endpoint (Source) -> Transport -> Function -checkTransportToIntermidiateRelation pu ifs rels = - let transMap = getTransportMap pu - lookup' v = fromMaybe (showError "Transport to Intermidiate" "transport" v) $ transMap M.!? v +-- TODO: remove pu +checkTransportToIntermidiateRelation ifs rels transMap pu = + let lookup' v = fromMaybe (showError "Transport to Intermidiate" "transport" v pu) $ transMap M.!? v makeRelationList = map S.fromList $ concatMap @@ -126,7 +127,8 @@ checkCadToFunctionRelation cadFs cadSteps pu = let consistent = S.isSubsetOf makeCadVertical rels rels = S.fromList $ filter isVertical $ relations $ process pu showLoop f = "bind " <> show f - lookup' v = fromMaybe (showError "CAD" "steps" v) $ cadSteps M.!? v + -- TODO: remove pu + lookup' v = fromMaybe (showError "CAD" "steps" v pu) $ cadSteps M.!? v makeCadVertical = S.fromList $ concatMap @@ -181,7 +183,7 @@ getTransportMap pu = filterTransport _ _ _ = Nothing in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu -getCadFunctions pu = +getCadFunctionsMap pu = let filterCad (_, f) | Just Loop{} <- castF f = True | Just (LoopBegin Loop{} _) <- castF f = True @@ -189,7 +191,7 @@ getCadFunctions pu = | otherwise = False in M.fromList $ filter filterCad $ M.toList $ getInterMap pu -getCadSteps pu = +getCadStepsMap pu = M.fromList [ (pDesc', pID) | step@Step{pID} <- steps $ process pu @@ -198,7 +200,7 @@ getCadSteps pu = _ -> [] ] -showError name mapName v = +showError name mapName v pu = error $ name <> " relations contain error: " @@ -206,3 +208,5 @@ showError name mapName v = <> " is not present in " <> mapName <> " map." + <> "proc: " + <> show (process pu) diff --git a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs index d47b20393..e4ca4665a 100644 --- a/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs +++ b/test/NITTA/Model/ProcessorUnits/Broken/Tests.hs @@ -110,44 +110,41 @@ tests = , expectFail $ typedLuaTestCase (maBroken def{lostEndpointSource = True}) pInt "typedLuaTestCase lost source endpoint" lua ] , testGroup - "broken relations integrity check" + "broken relations integrity check positive" [ nittaCoSimTestCase "nittaCoSimTestCase positive test" (maBroken u) alg , typedLuaTestCase (maBroken def) pInt "typedLuaTestCase positive test" lua , puCoSimTestCase "puCoSimTestCase positive test" u [("a", 42)] [brokenBuffer "a" ["b"]] + , finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u fsGen + , puCoSimProp "puCoSimProp relation positive test" u fsGen ] , testGroup - "broken relations integrity check" - [ --- TODO fix case when we have lost Intstruction but integrityCheck is OK - expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost instr and ep" u{lostInstructionRelation = True, lostEndpointRelation = True} fsGen + "broken relations integrity check negative base" + [ expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost instr and ep" u{lostInstructionRelation = True, lostEndpointRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Endpoints" u{lostEndpointRelation = True} fsGen , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Instruction" u{lostInstructionRelation = True} fsGen + , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost Endpoints" u{lostEndpointRelation = True} fsGen , expectFail $ puCoSimProp "puCoSimProp lost Instruction" u{lostInstructionRelation = True} fsGen + , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Instructions" u{lostInstructionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] + , expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] ] , testGroup - "broken relations integrity check" - [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Instructions" u{lostInstructionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] - , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Endpoints" (maBroken u{lostEndpointRelation = True}) alg + "broken relations integrity check negative coSim" + -- nittaCoSimTestCase has isLeaf and isComplete, but Relation alright because of CAD + -- TODO: below cases ignores lost because of CAD steps and failed because simulation + [ expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Endpoints" (maBroken u{lostEndpointRelation = True}) alg , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Instruction" (maBroken u{lostInstructionRelation = True}) alg , expectFail $ typedLuaTestCase (maBroken def{lostEndpointRelation = True}) pInt "typedLuaTestCase lost Endpoints" lua , expectFail $ typedLuaTestCase (maBroken def{lostInstructionRelation = True}) pInt "typedLuaTestCase lost Instruction" lua ] , testGroup - "broken relations integrity check fails" - [ finitePUSynthesisProp "finitePUSynthesisProp relation positive test" u fsGen - , puCoSimProp "puCoSimProp relation positive test" u fsGen - , expectFail $ puCoSimProp "puCoSimProp lost Function" u{lostFunctionRelation = True} fsGen - , expectFail $ finitePUSynthesisProp "finitePUSynthesisProp lost Function" u{lostFunctionRelation = True} fsGen + "broken relations integrity check negative fails" + -- TODO: try lua function without break loop + [ expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg + , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua ] - {- - , testGroup - "broken puCoSimTestCase" - [ expectFail $ puCoSimTestCase "puCoSimTestCase lost Function" u{lostFunctionRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] - , expectFail $ puCoSimTestCase "puCoSimTestCase lost Endpoints" u{lostEndpointRelation = True} [("a", 42)] [brokenBuffer "a" ["b"]] - , expectFail $ nittaCoSimTestCase "nittaCoSimTestCase lost Function" (maBroken u{lostFunctionRelation = True}) alg - , expectFail $ typedLuaTestCase (maBroken def{lostFunctionRelation = True}) pInt "typedLuaTestCase lost Function" lua - ] - -} ] where u = def :: Broken String Int Int From 3cabadeddd00bacbdedcb61bc621e5976d6b5bb3 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 30 May 2021 00:14:09 +0300 Subject: [PATCH 46/49] fix_edsl: removed ProcessConsistent instance for BusNetwork --- src/NITTA/Model/IntegrityCheck.hs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 1cd054466..81418ad28 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -24,8 +24,6 @@ import Data.Either import qualified Data.Map.Strict as M import Data.Maybe import qualified Data.Set as S -import Data.String (IsString) -import Data.String.ToString (ToString) import NITTA.Intermediate.Functions import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) @@ -44,15 +42,6 @@ instance (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessCo ] in checkResult isConsistent -instance (ProcessorUnit u v x t, Typeable u, IsString u, ToString u, Ord u) => ProcessConsistent (BusNetwork u v x t) where - checkProcessСonsistent pu = - let isConsistent = - [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu - , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu - , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu - ] - in checkResult isConsistent - checkResult res = if any isLeft res then Left $ concat $ lefts res From d32ac1caa2e1c3893f6fb52cd91e61e1919db66f Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 30 May 2021 14:26:51 +0300 Subject: [PATCH 47/49] fix_integrity: added incoherent for `Bus` in `ProcessConsistest` --- src/NITTA/Model/IntegrityCheck.hs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 81418ad28..8d460e9ff 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -29,11 +29,12 @@ import NITTA.Intermediate.Types import NITTA.Model.Networks.Bus (BusNetwork, Instruction (Transport)) import NITTA.Model.ProcessorUnits import NITTA.Utils +import NITTA.Utils.ProcessDescription class ProcessConsistent u where checkProcessСonsistent :: u -> Either String () -instance (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessConsistent (pu v x t) where +instance {-# OVERLAPS #-} (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessConsistent (pu v x t) where checkProcessСonsistent pu = let isConsistent = [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu @@ -42,6 +43,11 @@ instance (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessCo ] in checkResult isConsistent +instance {-# INCOHERENT #-} ProcessConsistent (BusNetwork u v x t) where + checkProcessСonsistent pu = + let isConsistent = [Left "Trying to run BusNetwork"] + in checkResult isConsistent + checkResult res = if any isLeft res then Left $ concat $ lefts res @@ -172,6 +178,13 @@ getTransportMap pu = filterTransport _ _ _ = Nothing in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu +getTransportMapBus pu = + let filterTransport pu' (InstructionStep ins) + | Just (Transport v _ _) <- castInstruction pu' ins = Just v + | otherwise = Nothing + filterTransport _ _ = Nothing + in M.mapMaybe (filterTransport pu) $ getInstrMap pu + getCadFunctionsMap pu = let filterCad (_, f) | Just Loop{} <- castF f = True From 175a7696f8ac48f9da136d035357225b258c0b48 Mon Sep 17 00:00:00 2001 From: artyom Date: Sun, 30 May 2021 14:51:07 +0300 Subject: [PATCH 48/49] fix_edsl: now can compile with BusNetwork instance of ProcessConsistent --- src/NITTA/Model/IntegrityCheck.hs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 8d460e9ff..76bfea1e0 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -34,16 +34,23 @@ import NITTA.Utils.ProcessDescription class ProcessConsistent u where checkProcessСonsistent :: u -> Either String () -instance {-# OVERLAPS #-} (ProcessorUnit (pu v x t) v x2 t2, Typeable x, Typeable t) => ProcessConsistent (pu v x t) where +instance {-# OVERLAPS #-} (ProcessorUnit (pu v x t) v x2 t2) => ProcessConsistent (pu v x t) where checkProcessСonsistent pu = let isConsistent = - [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) M.empty pu , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu ] in checkResult isConsistent -instance {-# INCOHERENT #-} ProcessConsistent (BusNetwork u v x t) where +instance {-# INCOHERENT #-} (ProcessorUnit (pu v x t) v x2 t2, UnitTag (pu v x t)) => ProcessConsistent (BusNetwork (pu v x t) v x2 t2) where + checkProcessСonsistent pu = + let isConsistent = + [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu + , checkInstructionToEndpointRelation (getInstrMap pu) (getEpMap pu) $ process pu + , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu + ] + in checkResult isConsistent checkProcessСonsistent pu = let isConsistent = [Left "Trying to run BusNetwork"] in checkResult isConsistent From 5374c5042b4a7e87cd76a2bbf969282ebb685970 Mon Sep 17 00:00:00 2001 From: Aleksandr Penskoi Date: Sat, 9 Oct 2021 22:38:32 +0300 Subject: [PATCH 49/49] Fix errors, which prevent building. --- src/NITTA/Model/IntegrityCheck.hs | 19 ++++++++++--------- src/NITTA/Synthesis/Explore.hs | 4 +--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/NITTA/Model/IntegrityCheck.hs b/src/NITTA/Model/IntegrityCheck.hs index 76bfea1e0..48d313063 100644 --- a/src/NITTA/Model/IntegrityCheck.hs +++ b/src/NITTA/Model/IntegrityCheck.hs @@ -43,7 +43,7 @@ instance {-# OVERLAPS #-} (ProcessorUnit (pu v x t) v x2 t2) => ProcessConsisten ] in checkResult isConsistent -instance {-# INCOHERENT #-} (ProcessorUnit (pu v x t) v x2 t2, UnitTag (pu v x t)) => ProcessConsistent (BusNetwork (pu v x t) v x2 t2) where +instance {-# INCOHERENT #-} (ProcessorUnit (pu v x t) v x2 t2, UnitTag (pu v x t)) => ProcessConsistent (BusNetwork (pu v x t) v x2 t2) where checkProcessСonsistent pu = let isConsistent = [ checkEndpointToIntermidiateRelation (getEpMap pu) (getInterMap pu) (getTransportMap pu) pu @@ -51,9 +51,10 @@ instance {-# INCOHERENT #-} (ProcessorUnit (pu v x t) v x2 t2, UnitTag (pu v x , checkCadToFunctionRelation (getCadFunctionsMap pu) (getCadStepsMap pu) pu ] in checkResult isConsistent - checkProcessСonsistent pu = - let isConsistent = [Left "Trying to run BusNetwork"] - in checkResult isConsistent + +-- checkProcessСonsistent _pu = +-- let isConsistent = [Left "Trying to run BusNetwork"] +-- in checkResult isConsistent checkResult res = if any isLeft res @@ -186,11 +187,11 @@ getTransportMap pu = in M.fromList $ mapMaybe (uncurry $ filterTransport pu) $ M.toList $ getInstrMap pu getTransportMapBus pu = - let filterTransport pu' (InstructionStep ins) - | Just (Transport v _ _) <- castInstruction pu' ins = Just v - | otherwise = Nothing - filterTransport _ _ = Nothing - in M.mapMaybe (filterTransport pu) $ getInstrMap pu + let filterTransport pu' (InstructionStep ins) + | Just (Transport v _ _) <- castInstruction pu' ins = Just v + | otherwise = Nothing + filterTransport _ _ = Nothing + in M.mapMaybe (filterTransport pu) $ getInstrMap pu getCadFunctionsMap pu = let filterCad (_, f) diff --git a/src/NITTA/Synthesis/Explore.hs b/src/NITTA/Synthesis/Explore.hs index d26d95814..a12de78ec 100644 --- a/src/NITTA/Synthesis/Explore.hs +++ b/src/NITTA/Synthesis/Explore.hs @@ -31,7 +31,6 @@ import qualified Data.List as L import qualified Data.Map.Strict as M import qualified Data.Set as S import NITTA.Intermediate.Types -import NITTA.Model.IntegrityCheck import NITTA.Model.Networks.Bus import NITTA.Model.Problems.Bind import NITTA.Model.Problems.Dataflow @@ -119,9 +118,8 @@ isLeaf , sResolveDeadlockOptions = [] , sOptimizeAccumOptions = [] , sConstantFoldingOptions = [] - , sTarget } - } = checkIntegrity $ mUnit sTarget + } = True isLeaf _ = False isComplete = isSynthesisComplete . sTarget . sState