<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Maurizio,</p>
    <p>Thanks for the quick reply.<br>
    </p>
    <div class="moz-cite-prefix">On 23/10/2023 12:34, Maurizio
      Cimadamore wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:3194db3d-684c-4dda-8ec3-ced369ed88f6@oracle.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <p>Hi Chris,<br>
        this is a good question. The main reason as to why the check is
        there is this: the code this new segment-based method replaces
        is code that used to accept a ByteBuffer. The check you see
        there was added just to make sure we didn't run into new and
        unexpected situations.</p>
    </blockquote>
    Ah yes. That's kinda what I thought. <br>
    <blockquote type="cite"
      cite="mid:3194db3d-684c-4dda-8ec3-ced369ed88f6@oracle.com">
      <p>Moving forward I could see this relaxed, either by tweaking the
        API to accept an explicit layout from the user (so that the API
        can check if the user really wants unaligned floats). Or, by
        doing a different check which validates the maximum supported
        alignment against the vector species. E.g. I suppose loading an
        int[] into a DoubleVector is not ok - but
        float[]/int[]/short[]/char[]/byte[] in FloatVector should be ok.
        But, going down that path is messy: while heap segments keep
        track of their underlying Java array, which can then be used to
        perform validation, an off-heap segment doesn't have any
        particular alignment constraint. So (I think) we're back to the
        user providing a layout parameter to the load method.</p>
    </blockquote>
    <p>Yeah, I think an explicit layout would be the way to go here. And
      maybe a default of 4-byte aligned, JAVA_FLOAT, when not explicitly
      passed for heap backed segments. The default should be relatively
      straightforward to enable, behaving as if JAVA_FLOAT with the
      passed byte order.<br>
    </p>
    <p>-Chris.<br>
    </p>
    <blockquote type="cite"
      cite="mid:3194db3d-684c-4dda-8ec3-ced369ed88f6@oracle.com">
      <p>Maurizio<br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <p><br>
      </p>
      <div class="moz-cite-prefix">On 23/10/2023 12:10, Chris Hegarty
        wrote:<br>
      </div>
      <blockquote type="cite"
        cite="mid:c2238394-bd23-4d7b-abcd-e3eb1568eaee@gmail.com">
        <p>Hi,</p>
        <p>I'm curious about the restriction when loading from heap
          backed memory segments. E.g.<br>
        </p>
        <div style="background-color:#1e1f22;color:#bcbec4">
          <pre
style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"> <span
          style="color:#5f826b;font-style:italic;"> * </span><span
          style="color:#67a37c;font-style:italic;">@throws </span><span
          style="color:#5f826b;font-style:italic;">IllegalArgumentException if the memory segment is a heap segment that is
</span><span style="color:#5f826b;font-style:italic;">  *         not backed by a {</span><span
          style="color:#67a37c;font-style:italic;">@code </span><span
          style="color:#5f826b;font-style:italic;">byte[]} array.
</span><span style="color:#5f826b;font-style:italic;">  * </span><span
          style="color:#67a37c;font-style:italic;">...</span><span
          style="color:#cf8e6d;">
</span> FloatVector <span style="color:#56a8f5;">fromMemorySegment</span>(VectorSpecies<Float> species, MemorgSegment ms, ...)</pre>
        </div>
        <p>Which results in:<br>
        </p>
        <p>jshell> float[] arr = new float[] { 1, 2, 3, 4, 5, 6, 7, 8
          }<br>
          arr ==> float[8] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 }<br>
          <br>
          jshell> var vec =
          FloatVector.fromMemorySegment(FloatVector.SPECIES_PREFERRED,
          MemorySegment.ofArray(arr), 0, ByteOrder.nativeOrder())<br>
          |  Exception java.lang.IllegalArgumentException<br>
          |        at ScopedMemoryAccess.loadFromMemorySegment
          (ScopedMemoryAccess.java:334)<br>
          |        at FloatVector.fromMemorySegment0Template
          (FloatVector.java:3353)<br>
          |        at Float128Vector.fromMemorySegment0
          (Float128Vector.java:864)<br>
          |        at FloatVector.fromMemorySegment
          (FloatVector.java:2986)<br>
          |        at do_it$Aux (#43:1)<br>
          |        at (#43:1)<br>
          <br>
        </p>
        <p>I can see that this is deliberate ...</p>
        <div style="background-color:#1e1f22;color:#bcbec4">
          <pre
style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span
          style="color:#16baac;"> V </span><span style="color:#56a8f5;">loadFromMemorySegmentMasked</span>(...) {
   <span style="color:#7a7e85;">// @@@ Smarter alignment checking if accessing heap segment backing non-byte[] array
</span><span style="color:#7a7e85;">   </span><span
          style="color:#cf8e6d;">if </span>(msp.maxAlignMask() > <span
          style="color:#2aacb8;">1</span>) {
     <span style="color:#cf8e6d;">throw new </span>IllegalArgumentException();
   }</pre>
        </div>
        <p>Is this just temporary? I would expect the alignment to be as
          if `<font face="monospace">ValueLayout.JAVA_FLOAT.withByteAlignment(1)</font>`,
          no? Is the intent to eventually support other non-byte
          primitive array typed, and to require and check alignment? It
          should just work, right?</p>
        <p>--<br>
        </p>
        <p>The reason I ask about this is that over in Luceneland we're
          considering a switch to loading vector data from float[] to
          MemorySegment - which allows to load search vectors directly
          from the mmapped index file. But we still have some code paths
          which have float[], which may or may not be coming from the
          mmapped file. So we end up with something like this:</p>
        <p><font face="monospace"> dotProduct(float[] a, float[] b)</font></p>
        <p><font face="monospace"> dotProduct(float[] a, MemorySegment
            b)</font></p>
        <p><font face="monospace"> dotProduct(</font><font
            face="monospace">MemorySegment</font><font face="monospace">
            a, MemorySegment b)</font></p>
        <p>... and we have cosine and Euclidean distance too. We can of
          course write the three variants of the code (and we've done
          this), just that it would be desirable to have the float[]
          accepting methods just wrap and delegate to the MemorySegment
          variant. In our use case, we don't slice or offset into the
          heap segment, but I do see how things could get misaligned
          quite quickly, but again I expect this to behave as if with
          byte alignment(1).<br>
        </p>
        <p>Thanks,</p>
        <p>-Chris.<br>
        </p>
      </blockquote>
    </blockquote>
  </body>
</html>