Skip to content
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

Switch to / provide libjpeg-turbo #673

Closed
sdvillal opened this issue Nov 7, 2018 · 51 comments
Closed

Switch to / provide libjpeg-turbo #673

sdvillal opened this issue Nov 7, 2018 · 51 comments

Comments

@sdvillal
Copy link

sdvillal commented Nov 7, 2018

TL;DR; libjpeg-turbo is faster and arguably more standard than jpeg 9, while it is not a drop-in replacement for jpeg 9. Should we consider switching back to jpeg 8 and making libjpeg-turbo conda forge default implementation?

Copy and paste from conda-forge/staged-recipes#6842 (comment)

conda-forge and defaults use jpeg 9. I think turbo is just unused (even if installed, it is not drop in because its library major is 8 and therefore the so files do not clobber - which would be warned about by conda itself). If any library uses turbo, that gets the user into segfaulty risk.

Using jpeg 9 is IMO unfortunate because turbo is becoming the de-facto standard everywhere else: from browsers to linux distros passing by downstream libraries like opencv or tensorflow use or will be using turbo. In fact libjpeg-turbo is currently under consideration for becoming an official ISO/ITU-T reference jpeg implementation. That is for good reason: turbo is an amazing implementation that runs about anywhere and is just much faster - shameless plug, see this blogpost of mine: http://blog.loopbio.com/video-io-2-jpeg-decoding.html.

Unfortunately, turbo is purposely not an ABI drop-in replacement for libjpeg 9, but for libjpeg 8 (see https://libjpeg-turbo.org/About/Jpeg-9). And that has given us a fair share of headaches in the past, to the extent that we went far to avoid symbol collision - but we thought our efforts were too hacky to try to push them into conda-forge. That is why you would see me being a bit conservative. Better safe than sorry.

I do not know about mixing turbo 8bit and 12bit in the same process, but I can only imagine that if used sloppily only the first version found by the dynamic loader will be used. Which I think at the moment would mean, at the very least, some surprises for the user intending to use 8bit, but getting 12bits, or vice-versa.

To my mind, the safest move is to depend on jpeg 9 like the rest of the stack. The right move, to my mind, should be to move defaults/conda-forge channels to use turbo. But I do not really know how hard that would be. Now, this is with my baggage. If you get to test this properly and are comfortable we are not getting our users into trouble by mixing several libraries (I do not know, maybe playing with symbol visibility/versioning, or just assuming that no trouble will happen), go ahead and provide that speedup, that should always be welcome.

A small read: http://www.fcollyer.com/2013/01/04/elf-symbol-visibility-and-the-perils-of-name-clashing/
Our renaming hack to avoid symbol collision: https://github.com/loopbio/libjpeg-turbo-feedstock
A test in our opencv build: https://github.com/loopbio/opencv-feedstock/blob/loopbio/recipe/ensure_jpegturbo_opencv_plays_nicely_with_jpeg9.py

@ocefpaf
Copy link
Member

ocefpaf commented Nov 8, 2018

I'm in favor of this change. Maybe we can out up a migrator, ping @CJ-Wright, to implement this change. I believe the first step would be check its ABI and add a pin to the conda-forge-pinning package.

@CJ-Wright
Copy link
Member

I think pinning would be a first good step. It could be possible to make a migrator for this. Another good first step would be to find the scope of the migration (how many things use 'jpeg').

@CJ-Wright
Copy link
Member

@conda-forge/bot

@CJ-Wright
Copy link
Member

@sdvillal any interest in putting a PR into regro/cf-scripts for a new migrator? I'm happy to walk you through the process/review PRs.

@sdvillal
Copy link
Author

sdvillal commented Nov 9, 2018

I think this change should be made in coordination with defaults, otherwise we risk introducing quite a sneaky incompatibility between both stacks. I also do not know if any downstream dependency do require jpeg 9 (@jakirkham seemed to have some vague memories for this).

@CJ-Wright yeah, I can do that. I'm a bit short of bandwidth until around mid next-week, I will likely start then.

@ocefpaf from https://abi-laboratory.pro/?view=timeline&l=libjpeg-turbo I would pin to x.x (there was a soname change between 1.2 and 1.3).

@sdvillal
Copy link
Author

sdvillal commented Nov 9, 2018

Actually maybe we should keep the pin to x (ABI seems really stable and that soname change is more of a false positive).

@sdvillal
Copy link
Author

sdvillal commented Nov 9, 2018

Since with conda we cannot say "libjpeg-turbo provides jpeg", I think building jpeg packages for versions (6, 8) that actually just install turbo is our safest bet to avoid parallel installs.

@ocefpaf
Copy link
Member

ocefpaf commented Nov 9, 2018

Sound reasonable to me. Thanks for looking into this @sdvillal!

@msarahan
Copy link
Member

msarahan commented Nov 9, 2018 via email

@jschueller
Copy link
Contributor

hi @msarahan, any updates on this ?

@isuruf
Copy link
Member

isuruf commented Jan 21, 2020

@jschueller, please send a PR to libjpeg-turbo-feedstock to add a new output jpeg with version 8d and depends on libjpeg-turbo. Also add build: track_features: jpeg_impl_libjpeg_turbo to make it not the default.

@jschueller
Copy link
Contributor

@jschueller
Copy link
Contributor

jschueller commented Jan 21, 2020

I see, so then we can pin jpeg to 8d instead of 9 in the whole stack, then we can make the switch, right ?

@jakirkham
Copy link
Member

@jschueller, I think people have already been doing work on this. Would talk to @hmaarrfk who I believe was leading this effort.

@hmaarrfk
Copy link
Contributor

I made a PR to the migrator to start to build out jpeg 8d again. There was some discussion about whether or not we should build both ajpeg 8 and 9

@jschueller
Copy link
Contributor

I'm curious to know about the v9 motivations

@hmaarrfk
Copy link
Contributor

For me it is just that precedent is hard to change

Follow progress here
conda-forge/conda-forge-pinning-feedstock#378

@hmaarrfk
Copy link
Contributor

Could we use a name migrator and just skip the whole abi compatibility constraint?

I'm trying to find the matplotlib -> matplotlib-base migrator but I can't seem to find it.

Would something like that be acceptable?

Since turbo is so widely used, I don't anticipate much breakage we won't be able to address.

@isuruf
Copy link
Member

isuruf commented May 31, 2020

Nope. You would then end up with some packages linking to libjpeg-turbo and some linking to jpeg.

@hmaarrfk
Copy link
Contributor

So we would have to make that exclusive package or libjpeg-turbo and jpeg before we start the migration right?

@hmaarrfk
Copy link
Contributor

during migrations, there are always some packages built against the "old version" while some packages are built with the "new version" right?

@hmaarrfk
Copy link
Contributor

hmaarrfk commented Jun 1, 2020

@isuruf this seems to be above my level skills ensuring things stay backward compatible.

I might simply suggest cutting out losses and:

  1. Pulling the jpeg8 package from conda-forge
  2. Making jpeg8 synonymous with libjpeg-turbo

calling things a day.

Defaults doesn't provide jpeg8 so that might solve the compatibility issue.

@traversaro
Copy link
Contributor

Given that conda-forge/conda-forge-pinning-feedstock#4945 was merged, perhaps we can close this issue? Or there something else to fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests