kornelski / dssim

Image similarity comparison simulating human perception (multiscale SSIM in Rust)
https://kornel.ski/dssim
GNU Affero General Public License v3.0
1.07k stars 69 forks source link

Fails to build on armv5, armv7, armv7l and ppc #132

Closed th0ma7 closed 1 year ago

th0ma7 commented 1 year ago

I've been trying to add dssim art of my integration project for providing gstreamer https://github.com/SynoCommunity/spksrc/pull/5298

I've noticed that it fails to build on some archs, namely armv5, armv7, armv7l and ppc. On the other hand it builds fine on i686, x86_64 and aarch64.

I suspect I have to disable neon and simd from the build process but unsure how to do that.

Here is the log output I get on armv7 which seems to point to neon acceleration :

The following warnings were emitted during compilation:

warning: In file included from vendor/simd/arm/jcgray-neon.c:32:
warning: vendor/simd/arm/jcgryext-neon.c: In function ‘jsimd_rgb_gray_convert_neon’:
warning: /home/spksrc/gstreamer/spksrc/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/8.5.0/include/arm_neon.h:12221:1: error: inlining failed in call to always_inline ‘vld3q_u8’: target specific option mismatch
warning:  vld3q_u8 (const uint8_t * __a)
warning:  ^~~~~~~~
warning: In file included from vendor/simd/arm/jcgray-neon.c:44:
warning: vendor/simd/arm/jcgryext-neon.c:67:35: note: called from here
warning:        uint8x16x3_t input_pixels = vld3q_u8(inptr);
warning:                                    ^~~~~~~~~~~~~~~
warning: In file included from vendor/simd/arm/jcgray-neon.c:32:
warning: /home/spksrc/gstreamer/spksrc/toolchain/syno-armv7-7.1/work/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/8.5.0/include/arm_neon.h:7353:1: error: inlining failed in call to always_inline ‘vget_low_u8’: target specific option mismatch
warning:  vget_low_u8 (uint8x16_t __a)
warning:  ^~~~~~~~~~~
warning: In file included from vendor/simd/arm/jcgray-neon.c:44:
warning: vendor/simd/arm/jcgryext-neon.c:69:24: note: called from here
warning:        uint16x8_t r_l = vmovl_u8(vget_low_u8(input_pixels.val[RGB_RED]));
warning:                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...

On armv5 the error is somewhat different but also pointing toward neon:

   Compiling lcms2 v5.5.0
The following warnings were emitted during compilation:

warning: In file included from vendor/simd/arm/jcphuff-neon.c:33:0:
warning: /home/spksrc/gstreamer/spksrc/toolchain/syno-88f6281-6.1/work/arm-marvell-linux-gnueabi/bin/../lib/gcc/arm-marvell-linux-gnueabi/4.6.4/include/arm_neon.h:32:2: error: #error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h
warning: In file included from vendor/simd/arm/jcgray-neon.c:32:0:
warning: /home/spksrc/gstreamer/spksrc/toolchain/syno-88f6281-6.1/work/arm-marvell-linux-gnueabi/bin/../lib/gcc/arm-marvell-linux-gnueabi/4.6.4/include/arm_neon.h:32:2: error: #error You must enable NEON instructions (e.g. -mfloat-abi=softfp -mfpu=neon) to use arm_neon.h
warning: vendor/simd/arm/jcphuff-neon.c: In function 'jsimd_encode_mcu_AC_first_prepare_neon':
warning: vendor/simd/arm/jcphuff-neon.c:53:5: error: unknown type name 'int16x8_t'
warning: vendor/simd/arm/jcphuff-neon.c:61:5: error: unknown type name 'int16x8_t'
warning: vendor/simd/arm/jcphuff-neon.c:71:5: error: unknown type name 'int16x8_t'
warning: vendor/simd/arm/jcphuff-neon.c:72:5: error: unknown type name 'int16x8_t'
...

While ppc point to simd:

error: failed to run custom build command for `mozjpeg-sys v1.0.3`

Caused by:
  process didn't exit successfully: `/home/spksrc/gstreamer/spksrc/cross/dssim/work-qoriq-6.1/dssim-3.2.3/target/release/build/mozjpeg-sys-23cc510cb6e39b16/build-script-build` (exit status: 101)
  --- stdout
  cargo:include=/home/spksrc/gstreamer/spksrc/cross/dssim/work-qoriq-6.1/dssim-3.2.3/target/powerpc-unknown-linux-gnu/release/build/mozjpeg-sys-657a34d37ba53121/out/include:/home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/mozjpeg-sys-1.0.3/vendor
  cargo:lib_version=62

  --- stderr
  thread 'main' panicked at '"with_simd" feature flag has been enabled in mozjpeg-sys crate on powerpc platform, which is does not have SIMD acceleration in MozJPEG. Disable SIMD or compile for x86/ARM/MIPS.', /home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/mozjpeg-sys-1.0.3/src/build.rs:279:13
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to compile `dssim v3.2.3 (/home/spksrc/gstreamer/spksrc/cross/dssim/work-qoriq-6.1/dssim-3.2.3)`, intermediate artifacts can be found at `/home/spksrc/gstreamer/spksrc/cross/dssim/work-qoriq-6.1/dssim-3.2.3/target`
make[1]: *** [../../mk/spksrc.cross-rust.mk:59: rust_install_target] Error 101
make[1]: Leaving directory '/home/spksrc/gstreamer/spksrc/cross/dssim'
kornelski commented 1 year ago

These errors all come from mozjpeg, which is a C library that includes platform-specific assembly. I've tweaked mozjpeg's build script for powerpc and arm-that-needs-neon flag. Maybe it will work? I don't have a setup to test it.

Run cargo update to get the latest version.

Also dssim 3.2.4 doesn't use mozjpeg by default any more. It uses a pure-Rust jpeg decoder, which may be easier to build. If you're not seeing the 3.2.4 release, it means your Rust version is unsupported. Run rustup update or if you're using Debian's Rust, uninstall it and never use Debian's Rust.

th0ma7 commented 1 year ago

Thnx, this is great! Tested 3.2.4 release and most of it is now solved :)

only ppc remaining with this new error build-qoriq-6.1.log:

   Compiling foreign-types v0.5.0
   Compiling lcms2 v5.5.0
   Compiling load_image v3.0.1
error[E0277]: the trait bound `rgb::RGB<u16>: pixel_format::LcmsPixelFormat` is not satisfied
  --> /home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/load_image-3.0.1/src/convert.rs:60:13
   |
60 |             self.apply_profile(Profile::new_icc(profiles::CMYK).unwrap())
   |             ^^^^ ------------- required by a bound introduced by this call
   |             |
   |             the trait `pixel_format::LcmsPixelFormat` is not implemented for `rgb::RGB<u16>`
   |
   = help: the trait `pixel_format::LcmsPixelFormat` is implemented for `rgb::RGB<u8>`
note: required for `[pixel_format::CMYK]` to implement `Convertible<rgb::RGB<u16>>`
  --> /home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/load_image-3.0.1/src/convert.rs:94:20
   |
94 
| impl<T, Converted> Convertible<Converted> for [T]
   |                    ^^^^^^^^^^^^^^^^^^^^^^     ^^^

error[E0277]: the trait bound `rgb::RGB<u16>: pixel_format::LcmsPixelFormat` is not satisfied
  --> /home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/load_image-3.0.1/src/convert.rs:59:48
   |
59 |         converted = profile.and_then(|profile| self.apply_profile(profile)).or_else(||{
   |                                                ^^^^ ------------- required by a bound introduced by this call
   |                                                |
   |                                                the trait `pixel_format::LcmsPixelFormat` is not implemented for `rgb::RGB<u16>`
   |
   = help: the trait `pixel_format::LcmsPixelFormat` is implemented for `rgb::RGB<u8>`
note: required for `[pixel_format::CMYK]` to implement `Convertible<rgb::RGB<u16>>`
  --> /home/spksrc/gstreamer/spksrc/distrib/cargo/registry/src/github.com-1ecc6299db9ec823/load_image-3.0.1/src/convert.rs:94:20
   |
94 | impl<T, Converted> Convertible<Converted> for [T]
...
kornelski commented 1 year ago

Ooof. There's #[cfg(target_endian = "little")] in the code.

kornelski commented 1 year ago

I've removed the conditional endian code. Run cargo update and it should compile. Maaaybe it will even work. Or CMYK JPEGs and 16-bit PNGs may be broken on big-endian PPC. Sadly, all my big endian Macs are long gone.

th0ma7 commented 1 year ago

Success :) That is really awesome! Thnx a lot! build-qoriq-6.1.log