The copyFromVec functions call dimPositions to get all the steps and
offsets to copy. That worked well for the non-empty matrices, but for the
empty one, dimPositions returns [[]].
copyToVec = do
for_ (zip [0,channels..] $ dimPositions shape) $ \(posIx, pos) -> do
let elemPtr = matElemAddress dataPtr step pos
for_ [0 .. channels - 1] $ \channelIx -> do
e <- peekElemOff elemPtr $ fromIntegral channelIx
VUM.unsafeWrite v (fromIntegral $ posIx + channelIx) e
dimsPositions (shape = []) producing [[]] results in pos = [],
and thus the poke*/peek* is executed at least once, even though there exist
no elements to run on.
(matElemAddress just uses sum [] in that case, thus producing an invalid
element offset of 0` -- the first element, when there are none.)
This commit fixes it by making dimPositions [] = [] instead of [[]],
thus the for_ loops never bring a pos = [] into being.
Also:
Ensure that matElemAddress checks its precondition.
The type Ptr Word8 -> [Int] -> [Int] -> Ptr a already reveals
that there must be one / that this function should be partial,
because which valid element Ptr ought to be
returned if the given lists are empty?
base's NonEmpty would be a better type than these lists.
Add a test against this.
Before this commit, this test would make the test suite output
test-opencv: lost signal due to full pipe: 11
indefinitely.
With the added error, it would be raised.
With the added fix, it passes.
Fixes #150.
The
copyFromVec
functions calldimPositions
to get all the steps and offsets to copy. That worked well for the non-empty matrices, but for the empty one,dimPositions
returns[[]]
.The empty matrix can have channels, e.g.
S 1
inThus in copcode like
or
dimsPositions (shape = [])
producing[[]]
results inpos = []
, and thus thepoke*
/peek*
is executed at least once, even though there exist no elements to run on. (matElemAddress
just usessum []
in that case, thus producing an invalid element offset of 0` -- the first element, when there are none.)This commit fixes it by making
dimPositions [] = []
instead of[[]]
, thus thefor_
loops never bring apos = []
into being.Also:
matElemAddress
checks its precondition. The typePtr Word8 -> [Int] -> [Int] -> Ptr a
already reveals that there must be one / that this function should be partial, because which valid element Ptr ought to be returned if the given lists are empty?base
's NonEmpty would be a better type than these lists.error
, it would be raised. With the added fix, it passes.