<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I have been thinking about this problem some time ago, and I think it should be possible. What Reiner wants is a way to store boxed values(that means they may be unlifted / lifted mixed) into the same array. For example, to implement HMAT efficiently, we may want to mix `ArrayArray# Node`(which are pointers pointing to next level) and some boxed value `a` into a same `ArrayArray# Node`. But I don’t think the API proposed by Reiner is ideal, adding new primitive types like `MixedArray# a b / MixedArray# a b c …` may works better.</div><div class=""><br class=""></div><div class="">Note currently we can store unlifted boxed value already, primitive package use unsafeCoerce# to achieve this, i.e. the `PrimUnlifted` class. But we can’t mix boxed unlifted value and boxed lifted value.</div><div class=""><br class=""></div><div class="">Cheers~</div><div class="">Winter</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On 17 Nov 2017, at 7:13 PM, Simon Peyton Jones via Libraries <<a href="mailto:libraries@haskell.org" class="">libraries@haskell.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="WordSection1" style="page: WordSection1; font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="margin: 0cm 0cm 0.0001pt 36pt; font-size: 11pt; font-family: Calibri, sans-serif;" class="">. I'd like to exploit this to put unlifted and lifted pointers into the same array<span style="font-size: 12pt;" class=""><o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class="">I think this’ll be ok provided both are pointers. You cannot put an Int# in place of a pointer (whether the latter is lifted or unlifted) or you’ll crash the GC.<o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class="">So your type for coerceToUnlifted looks too general to me.<o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class="">But I have not devoted enough time to be certain.<o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class="">Hope this helps a little<o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class="">Simon<o:p class=""></o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><span style="font-size: 12pt;" class=""><o:p class=""> </o:p></span></div><div style="border-style: none none none solid; border-left-width: 1.5pt; border-left-color: blue; padding: 0cm 0cm 0cm 4pt;" class=""><div class=""><div style="border-style: solid none none; border-top-width: 1pt; border-top-color: rgb(225, 225, 225); padding: 3pt 0cm 0cm;" class=""><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><b class=""><span lang="EN-US" class="">From:</span></b><span lang="EN-US" class=""><span class="Apple-converted-space"> </span>Libraries [<a href="mailto:libraries-bounces@haskell.org" class="">mailto:libraries-bounces@haskell.org</a>]<span class="Apple-converted-space"> </span><b class="">On Behalf Of<span class="Apple-converted-space"> </span></b>Reiner Pope<br class=""><b class="">Sent:</b><span class="Apple-converted-space"> </span>17 November 2017 05:38<br class=""><b class="">To:</b><span class="Apple-converted-space"> </span><a href="mailto:libraries@haskell.org" class="">libraries@haskell.org</a><br class=""><b class="">Subject:</b><span class="Apple-converted-space"> </span>Storing lifted and unlifted pointer types in the same Array#<o:p class=""></o:p></span></div></div></div><div style="margin: 0cm 0cm 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;" class=""><o:p class=""> </o:p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">Hi libraries@,<o:p class=""></o:p></p><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">In GHC.Prim, it is documented that Array# and ArrayArray# have the same runtime representation. I'd like to exploit this to put unlifted and lifted pointers into the same array (for example, unlifted pointers at even indices and lifted pointers at odd indices). The reason I want to do this is to save some array header words, and also to improve the cache locality of my data, so that a read of a (lifted, unlifted) pointer pair only needs to touch a single cache line rather than two.<o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">I believe it is safe to do this (put unlifted and lifted pointers in the same array), as long as I always read at the same liftedness and type that I ran the write at for that index. Can you confirm?<o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">Specifically, I'm expecting to use a code pattern like the following, to read an unlifted value from an Array#, by coercing the Array# to ArrayArray#, then doing the unlifted read there:<o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">coerceToArrayArray :: Array# a -> ArrayArray#</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">coerceToArrayArray = unsafeCoerce#</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">coerceToUnlifted :: forall (b :: TYPE 'UnliftedRep). ArrayArray# -> b</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">coerceToUnlifted = unsafeCoerce#</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">indexUnliftedFromArray ::</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class=""> forall a (b :: TYPE 'UnliftedRep). Array# a -> Int# -> b</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class="">indexUnliftedFromArray arr i =</span><o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><span style="font-family: 'Courier New';" class=""> coerceToUnlifted (indexArrayArrayArray# (coerceToArrayArray arr) i)</span><o:p class=""></o:p></p></div></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">Similarly, I'm expecting to do writes by coercing the array to a MutableArrayArray# and doing the writes to that.<o:p class=""></o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;"><o:p class=""> </o:p></p></div><div class=""><p class="MsoNormal" style="margin: 0cm 0cm 6pt; font-size: 11pt; font-family: Calibri, sans-serif;">Reiner<o:p class=""></o:p></p></div></div></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Libraries mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><a href="mailto:Libraries@haskell.org" class="">Libraries@haskell.org</a></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a></span></div></blockquote></div><br class=""></body></html>