<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/63469>63469</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [mlir] External resources on big-endian platforms
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          uweigand
      </td>
    </tr>
</table>

<pre>
    Parsing external resources currently fails on big-endian platforms.  One typical example from the `unittests/Bytecode/BytecodeTest.cpp` unit test looks like this:
```
module @TestDialectResources attributes {
  bytecode.test = dense_resource<resource> : tensor<4xi32>
} {}
{-#
 dialect_resources: {
    builtin: {
      resource: "0x1000000001000000020000000300000004000000"
    }
 }
#-}
```

Note how there are two distinct elements: a `dense_resource` attribute, which is typed and refers to a named blob, and the named blob itself, which is untyped and part of a dialect-specific resource record.  These elements are also parsed independently: the `dense_resource` attribute is parsed by the `parseDenseResourceElementsAttr` routine which returns a `DenseResourceElementsAttr` class containing two data elements - the type and a `DenseResourceElementsHandle` refering to the blob by name -, while the blob is parsed by the `parseDialectResourceFileMetadata` using a dialect-specific `parseResource` callback which in this case creates an `AsmResourceBlob` structure and associates it with the `DenseResourceElementsHandle` for the name.

The external representation of the blob data is always little-endian, and it is read without conversion into the `AsmResourceBlob`.  However, when the `DenseResourceElementsAttr` class is used to look at its elements, the code assumes that the contents of the associated `AsmResourceBlob` are in native host endianness - this is the root cause of the current failures on big-endian hosts.

Complicating the matter further is that there is a second path to creating `DenseResourceElementsAttr` instances via the `DenseResourceElementsAttrBase<T>::get` constructor - and here the blob data is copied from input data that is already presented in native byte order.  So on a big-endian system we end up with some instances containing big-endian data while others contain little-endian data, and no way for the accessor routines to even distinguish between the two cases.

To fix this, the first decision to make is what the format of the data stored inside the `DenseResourceElementsAttr` is even supposed to be.  One natural choice would be to require this data to be always stored in native byte order, which makes accessors very simple and matches the approach used for `DenseElementsAttr`. This would require data read from external resources to be converted.

However, the problem is the two-phase parsing process (which in turn is already enforced by the syntax of the MLIR file).  At the point where we read in the blob data, we actually do not know the *type* the data will be accessed in, and therefore cannot convert.  Vice versa, at the point where we create the `DenseResourceElementsAttr`, we know the type - but the blob data is not yet parsed so we cannot convert here either.   In fact, I guess it might be possible that the same blob is referenced by *multiple* `dense_resource` attributes using different types, so it would have to be converted *differently*.

One option to fix this might be to extend the `DenseResourceElementsAttr` class to carry a second reference to a blob (in addition to the implicit reference via the `DenseResourceElementsHandle`). This would initially be null, and on first access to the associated blob would be filled by converting the blob from the handle using the type from the attribute.  Further accesses would then use directly the already-translated blob from the `DenseResourceElementsAttr`.   Note that there may be some issues with where exactly to store this second blob and how to manage its life time - any suggestions would be appreciated here.

The other choice might be to define the blobs associated with `DenseResourceElementsAttr` to be always stored in little-endian format to begin with.  This would avoid any conversion issues when reading in external resources.  However, we would now need to convert all blobs passed in to `DenseResourceElementsAttrBase<T>::get` back to little-endian format (which is feasible as the type is known at this place).

In addition, all accessors would have to be reworked.  The latter cannot be done without visible API changes - the current API 
```
  /// Return the data of this attribute as an ArrayRef<T> if it is present,
  /// returns std::nullopt otherwise.
  std::optional<ArrayRef<T>> tryGetAsArrayRef() const;
```
cannot "hide" any conversion on access time, so all users would have to be prepared to e.g. operate on `ulittle64_t` instead of `uint64_t`.

I'd be happy to work on the implementation of either of the above approaches, but I'd appreciate feedback as to which direction you prefer.

CC @River707 @jpienaar @joker-eph 



</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycWFtv4zjS_TXKS8GGW3I7yUMenKTzTQPf7A6ywb4OKKlkcUKRWrJkx_9-UUXq4iTdPdhGI76Il7qcOqfKKgR9sIh32df77OvjlRqodf5uOKE-KFtfla4-3_2hfND2APhG6K0y4DG4wVcYoBq8R0vmDI3SJoCzUOrDCm2tlYXeKGqc78Ia4J8Wgc69rpQBfFNdbxAa7zqgFiHbbQariTBQyPKn-zNh5WpcvH3BQOuq77PdBngp8Fowzr0GMPoVgVodsmKfbR6zzT7bbdJ_-di5ejAI2XbDxzxqZbCi58kJReR1ORAGyK7v4xaAMt28lpuy4hFqtAH_HJ3Piof57TfIij0Q2uB8Vjxs33SRZ8W3ZM31oxx8_Th-vl9leZEuqqM507nsxdIOgHLQhrT98D3AbMAesjzfvH3ZpH_jmzy9Ful1G1-yPJ_PmQyb32V5sZo_XEYz_v2HI4TWnTh_HkF5BDo5qHUgbSsCNNihJfFGcYLfRW-3meOe5Q9wanXVgg4MEqxB2Ro8NugDkAMFVnVYQ2lcyYv5KeNm_hY0BTTNxUmDnc_qlSdwDagx3qvQY6UbXU1BBI-V8_Ua4KXFgJMH4psywfEhAWvQtsYebS3Al7xHCP_EQzYn7S7P43r54pE3jVj8lq7cE3ne791A2mJyySMN3oYYzp_uq4wKASpnSWnLpSupUaRmp1ZiBQdI4vPjM39TtjbijeRDTnOyWeJeniULsEqhNzg_-7HTlyX4pA3-jqTYQilwoZtPUjXuf17EuFLGlKp6HfNuhQqgUgGh8qi4rJXlrfvQjRvvGUi7DQTyQ0WDT0EIwVVadmiCk6Z2tPoXkWmcn_C4XlbJS4tL2uw9BrSkSDvLaJwiJbnRAZQ5qTMzGpHBRKMj4DXxCo-qFtPcQJzhI_rAp2mbsvKpo2uA39wJj-hjmtD-1LNLHHEpcRLJCeGCIq62ucLzBzmMyZJDOHQYgFpF6VtLArjk7hTj-gcp4WrTFqwifWSGCQQxDhZDhK0Wk_gw7xxBpYaA4_FJkESOBo_vFYmPCxcZenBdb3SlSIDdInSKCD00g2dmizdFX7yUsYKAlRNKYXy4CDLe_atoahtIWVaco1a_jP-9CqwxLywjxT4r9gckyYmzEbXOw0qAIZZ9gFLleo111Fht-4HiE3FGkMZIOkOCpNDaGHSWPnC-Rr8G-JfjGKplFMM5EHZwQs4MDH0sleA6XPi4YJ_FVrEh0oTjkE7rLjEv60bgWwcndZ6KTFUVhuD8yI6iEHhEm8TnMOjQQol0wgRzZj_mg8vMvzho9FtsHBKEG-0DQY2VlpoiB516layfRjxzP6NohJu4E8h5iV_QNf6tutIhGhyGvneptEpMXZJVNHhloGqdrhBObjA1lMhrPP5n0D42OymdvHGkjcmQj4mchZE9ClMQAxzRnyFoacg42p2iqsVYX6rvvVNVG-ufEzB69s6jNbywSdHW0UoxUPhKQPhJ-xitjyxGWF-kZ8FXbErvXWmwGyufTm7Vt8zxfepOe-_YJcjym1kJBm-XYEfbOF_NehTOltTbmMzf___7MzTaYJbfrgH2MeG905aYMj0y4sUfbS_rTaLLyKRBGXOG2oF1BK829keQ5XtW2izfz6g5aWMkd5IJSduitfHYOI9QKcsHpQitAf7NkGDOj9XxqYlR9f4OEJPdk53SDqygHOgjn7AdZ6RR0YOTqy7si0yEmu1fA8B3C42qiG_5DoeBs6MJOn1oiT3vXQi6lIYhORK4kxhbB2k30KZ0Zfm-Gwzp3kgYf95uhdRC1LqRM0g8kzIPTrRdgNqqI77HIF80bTPnLN9foJIL1PWU2GHkj9knpqI3wtSf_j19ZQ1R3p9naZlcj82vRCTLb7QFVdd6vJ1v0KJemhZbfiUuU9siMF_UrbaatOC3RLCDMSMenU3MGLE63r2QcrFwYqpGGxOzlsI6aqssm6a-VgxJqZrgNz2esrkGeEpqnIpltJi4kWH1r7XHisdQ2RirfUVe2WBm-5bj5s_SwtCV8WYh_J2SqESNC2FgE1j0YtHhm4q3u8jBERQpmXK36DRXGUuKVQeUFsroBoE0t8-g7BnCcDhg4PyGOZpMwpjizLd9aDBFSEe5WCKxxoanhzHyYZkxsf5X-PyBulxKdVJEWXvQVk6WIWoCljo6XYuDy4Y1RZFTyPliEGj7iUq8611HRWTOshi1c-QfxZQqnvYqcSo__l_aLBkpuOP9zNdZYwI0qCKLqTCDWAchVRsZmucgoyrRlWXyvs_1LKVmzEKXP1CUx5Pzr5gGVDCxT00MXCLUjifFNBkcdTRq_8d3qFplDziOfGOHzE8-ne8Bsvwp_odnGTln0RKl1IufTNhrZWHvvTo_Y5MiCbpJ40pqL7P84ePh4zwbqI6hZ85xPUVAn3QYoQ7zksi9ymTFw7s7-Vry5_9D2ofpUX6T5bexZc6K-0_dTQHM8rzVNWZ5_h6o3P0m3tMdJg3hXA0BP8tT77FXPgIT14c1uB49C7KTKXSIiNpt_6RxKOCWwjXyUFtKTy6RkuXXQgat6nvhGcYCnziKgCB6GiyjBk8zV-mOczMXdZA1Pp468ws0iLUAXwnJR4xHbuWDz25g7xr0lyPUA2TbzbM-or_eXPP7v3qNVikv790r-hX2LSz3xL9X9V1R3xa36grvvuxurr_mxbYortq7bbFRWDf1tqjrXXX7pS6qZoNYXRfbzW15W1_pu3yTF5tdXnzJi01RrK-_5vm23N3cNDfb6-1tlW032Clt1sYcu7XzhyshnLtdsd3dXhlVognyq2eeWzxFNsryPPv6eOXveM-qHA4h226M5pFxOoU0Gfm5tDPaZ18f4dvHtvYHv4JeDd7ctUS9_FApNXDQ1A7lunJdlj_xHell1Xv3F3Lr9BR5MsufxPL_BgAA__8uwnl7">