-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing endianess conversion for dense constant lowering to LLVM dialect #2851
Comments
Hi @Ansaya, thanks for looking at this! FYI, we are using Z machines which are big-endian also, and constants work fine on them. So I would like to understand more about your issue. Do you have IRs showing the information loss? and what is the information you need to preserver, or anything concrete examples. Though keeping the dense constants as they are would be the best, we have had to use strings here to avoid the poor performance when translating LLVMIR to LLVM: https://discourse.llvm.org/t/performance-issues-with-memref-global-and-llvm-ir/68604. It's really slow for big deep learning models. |
Here are the steps to reproduce the issue starting from the mnist model available in
The output of the two
After a quick hex-to-float conversion of the first element of
Please let me know if you can reproduce the issue. P.S. I did not use the |
@Ansaya thank you for the example! I followed your steps and ran on a Z machine, and the result looked good:
One thing I was noticed is |
If this solves your issue, I am OK if you would like to add a compiler flag that disables dense-to-string conversion. |
This may be related to the fact that your build and target machine are the same, which is not true in my case. I build the executable on an X86 little-endian machine targeting a Sparc big-endian machine. Thus, the input weights have a different endianness with respect to the target. In your case, you may be able to reproduce the issue by setting a little-endian machine as the target. |
I am using onnx-mlir to build models for Sparc CPU target, which is big-endian, and I am facing a data conversion issue caused by the string type initialization used for large dense constants.
MLIR's IR and LLVM's IR expect the data representation to be little-endian until the code generation for the target system is performed; then, data is transformed to adhere to the target system's endianness according to the data type.
During the Krnl to LLVM lowering, dense raw data bigger than 1Kb is lowered to LLVM global constant as a string of bytes, thus losing the information relative to the actual data type of the initialized elements. Consequently, when code generation happens, the data endianness is not updated to that of the target system since string type is endianness independent. This leads to an incorrect constant data initialization for big-endian targets.
I understand that converting the dense constant data to a string saves space since LLVM IR stores floating-point constants as double, even for smaller data types, however, this removes the data type information needed for the endianness fix during the code generation step.
I want to contribute with a fix to this, but I would like to know which solution you think is the best for the case:
Please let me know if you are interested and what you think is the best approach to solve the issue.
The text was updated successfully, but these errors were encountered: