-
Notifications
You must be signed in to change notification settings - Fork 7k
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
PR: Add libpng and libjpeg-turbo requirement into conda recipe #2301
Changes from all commits
2b78943
23255aa
006ab0c
7b9ec24
f97a9f0
ac6d26e
b14912e
770cea5
0861b80
a42a029
b7a19ea
1afde4d
386fd5b
2b5c469
0341aa5
721e5e3
2186d68
b80fb08
3d153f0
36b0a8f
9d14d9e
852a289
3e86f49
021e767
e734175
58c6524
b9295c1
02fa9d9
6c757d4
c207eab
a1aa2e6
34fc7d6
3ed2044
eaaf658
3edae46
c17202e
741f855
a46f503
4bad033
b419fc1
83eff79
eb2846f
3563ef3
347383f
51f6b48
ad00442
4d82283
32b2207
9a5aefe
a44c3b5
dfcde68
d8d46d6
eea8552
8c7dc31
ee8148a
059fa42
0ed1af6
11d1a7a
3bb65ba
c334d7e
5650e59
7894836
2da51d4
78455ae
a0a383d
f143e2c
95cc941
1c9270a
ee388e5
462ed6c
989db57
6e9ad0e
dd43bcd
e542e48
b5fa45e
3e90556
4e09af0
c2e9bf3
8ac335e
2adb87e
44826a7
1e830ea
37c889b
3cca366
2a6ff9f
b89b349
264cb74
a0ce4ca
bd752aa
5259757
3013247
9d8b1b5
7c3ec51
158eec8
269d8e5
273dc1a
cfc7c75
d32a5f0
051425b
3bc7323
6b87895
af61f94
123fd3f
831749c
558b0cb
8b2f507
b560227
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
channel_sources: | ||
- defaults,conda-forge | ||
|
||
blas_impl: | ||
- mkl # [x86_64] | ||
c_compiler: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,8 @@ source: | |
requirements: | ||
build: | ||
- {{ compiler('c') }} # [win] | ||
- libpng | ||
- libjpeg-turbo | ||
|
||
host: | ||
- python | ||
|
@@ -18,6 +20,10 @@ requirements: | |
|
||
run: | ||
- python | ||
- libpng | ||
- libjpeg-turbo | ||
# Pillow introduces unwanted conflicts with libjpeg-turbo, as it depends on jpeg | ||
# The fix depends on https://github.com/conda-forge/conda-forge.github.io/issues/673 | ||
Comment on lines
+25
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain when / how these conflicts materialize? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The conflict here is that we're substituting the libjpeg library, which is used primarily by Pillow, however this may not affect us as the ABI between jpegturbo and libjpeg is the same AFAIK. Most Linux distributions distinguish between libturbojpeg (the library itself) and libjpeg-turbo (the libjpeg version using turbojpeg), thus, they do not have this problem, as we link against libturbojpeg, rather than against libjpeg-turbo. In conda-forge, we have this conflict because the recipe for libjpeg-turbo produces both the turbo flavored libjpeg and libturbojpeg. I spoke to @isuruf, one of the maintainers in conda-forge, and he told me that they are working towards a solution in conda-forge/conda-forge.github.io#673, but right now there are no alternatives to this conflict. I guess we are not having any problem with this conflicting installation, as the tests are passing. However, we should encourage users to install PyTorch and torchvision on a separate environment, so we prevent other errors that could be caused as part of this conflict and we're not aware of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hum, this makes me a bit worried, because AFAIK we don't have tests running on OSX, only Linux and Windows (we do compile on OSX though). Do you think that, if we were to use libjpeg API, everything would be safer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't they running on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh ok, yeah, we were not running tests for OSX with wheels, only conda. But still, do you think if we were to use libjpeg API it would make things safer? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think right now we don't have much trouble on our setup, as we are linking against libturbojpeg and not libjpeg directly. If we were compilling against libjpeg, then we would be in trouble. Right now the only conflict that we have is the one on conda-forge. A provisional solution would be compilling libturbojpeg (Without libjpeg) ourselves and publish it into the conda pytorch channel until conda-forge/conda-forge.github.io#673 is fixed. What do you think about this? |
||
- pillow >=4.1.1 | ||
- numpy >=1.11 | ||
{{ environ.get('CONDA_PYTORCH_CONSTRAINT') }} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
import re | ||
import sys | ||
from setuptools import setup, find_packages | ||
from pkg_resources import get_distribution, DistributionNotFound | ||
from pkg_resources import parse_version, get_distribution, DistributionNotFound | ||
import subprocess | ||
import distutils.command.clean | ||
import distutils.spawn | ||
|
@@ -76,7 +76,76 @@ def write_version_file(): | |
requirements.append(pillow_req + pillow_ver) | ||
|
||
|
||
def find_library(name, vision_include): | ||
this_dir = os.path.dirname(os.path.abspath(__file__)) | ||
build_prefix = os.environ.get('BUILD_PREFIX', None) | ||
is_conda_build = build_prefix is not None | ||
|
||
library_found = False | ||
conda_installed = False | ||
lib_folder = None | ||
include_folder = None | ||
library_header = '{0}.h'.format(name) | ||
|
||
print('Running build on conda-build: {0}'.format(is_conda_build)) | ||
if is_conda_build: | ||
# Add conda headers/libraries | ||
if os.name == 'nt': | ||
build_prefix = os.path.join(build_prefix, 'Library') | ||
include_folder = os.path.join(build_prefix, 'include') | ||
lib_folder = os.path.join(build_prefix, 'lib') | ||
library_header_path = os.path.join( | ||
include_folder, library_header) | ||
library_found = os.path.isfile(library_header_path) | ||
conda_installed = library_found | ||
else: | ||
# Check if using Anaconda to produce wheels | ||
conda = distutils.spawn.find_executable('conda') | ||
is_conda = conda is not None | ||
print('Running build on conda: {0}'.format(is_conda)) | ||
if is_conda: | ||
python_executable = sys.executable | ||
py_folder = os.path.dirname(python_executable) | ||
if os.name == 'nt': | ||
env_path = os.path.join(py_folder, 'Library') | ||
else: | ||
env_path = os.path.dirname(py_folder) | ||
lib_folder = os.path.join(env_path, 'lib') | ||
include_folder = os.path.join(env_path, 'include') | ||
library_header_path = os.path.join( | ||
include_folder, library_header) | ||
library_found = os.path.isfile(library_header_path) | ||
conda_installed = library_found | ||
|
||
# Try to locate turbojpeg in Linux standard paths | ||
if not library_found: | ||
if sys.platform == 'linux': | ||
library_found = os.path.exists('/usr/include/{0}'.format( | ||
library_header)) | ||
library_found = library_found or os.path.exists( | ||
'/usr/local/include/{0}'.format(library_header)) | ||
else: | ||
# Lookup in TORCHVISION_INCLUDE or in the package file | ||
package_path = [os.path.join(this_dir, 'torchvision')] | ||
for folder in vision_include + package_path: | ||
andfoy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
candidate_path = os.path.join(folder, library_header) | ||
library_found = os.path.exists(candidate_path) | ||
if library_found: | ||
break | ||
|
||
return library_found, conda_installed, include_folder, lib_folder | ||
|
||
|
||
def get_extensions(): | ||
vision_include = os.environ.get('TORCHVISION_INCLUDE', None) | ||
vision_library = os.environ.get('TORCHVISION_LIBRARY', None) | ||
vision_include = (vision_include.split(os.pathsep) | ||
if vision_include is not None else []) | ||
vision_library = (vision_library.split(os.pathsep) | ||
if vision_library is not None else []) | ||
include_dirs = vision_include | ||
library_dirs = vision_library | ||
|
||
this_dir = os.path.dirname(os.path.abspath(__file__)) | ||
extensions_dir = os.path.join(this_dir, 'torchvision', 'csrc') | ||
|
||
|
@@ -149,13 +218,14 @@ def get_extensions(): | |
|
||
sources = [os.path.join(extensions_dir, s) for s in sources] | ||
|
||
include_dirs = [extensions_dir] | ||
include_dirs += [extensions_dir] | ||
|
||
ext_modules = [ | ||
extension( | ||
'torchvision._C', | ||
sources, | ||
include_dirs=include_dirs, | ||
library_dirs=library_dirs, | ||
define_macros=define_macros, | ||
extra_compile_args=extra_compile_args, | ||
) | ||
|
@@ -171,6 +241,65 @@ def get_extensions(): | |
) | ||
) | ||
|
||
# Image reading extension | ||
image_macros = [] | ||
image_include = [extensions_dir] | ||
image_library = [] | ||
image_link_flags = [] | ||
|
||
# Locating libPNG | ||
libpng = distutils.spawn.find_executable('libpng-config') | ||
png_found = libpng is not None | ||
image_macros += [('PNG_FOUND', str(int(png_found)))] | ||
print('PNG found: {0}'.format(png_found)) | ||
if png_found: | ||
png_version = subprocess.run([libpng, '--version'], | ||
stdout=subprocess.PIPE) | ||
png_version = png_version.stdout.strip().decode('utf-8') | ||
print('libpng version: {0}'.format(png_version)) | ||
png_version = parse_version(png_version) | ||
if png_version >= parse_version("1.6.0"): | ||
print('Building torchvision with PNG image support') | ||
png_lib = subprocess.run([libpng, '--libdir'], | ||
stdout=subprocess.PIPE) | ||
png_include = subprocess.run([libpng, '--I_opts'], | ||
stdout=subprocess.PIPE) | ||
image_library += [png_lib.stdout.strip().decode('utf-8')] | ||
image_include += [png_include.stdout.strip().decode('utf-8')] | ||
image_link_flags.append('png' if os.name != 'nt' else 'libpng') | ||
else: | ||
print('libpng installed version is less than 1.6.0, ' | ||
'disabling PNG support') | ||
png_found = False | ||
|
||
# Locating libjpegturbo | ||
turbojpeg_info = find_library('turbojpeg', vision_include) | ||
(turbojpeg_found, conda_installed, | ||
turbo_include_folder, turbo_lib_folder) = turbojpeg_info | ||
|
||
image_macros += [('JPEG_FOUND', str(int(turbojpeg_found)))] | ||
print('turboJPEG found: {0}'.format(turbojpeg_found)) | ||
if turbojpeg_found: | ||
print('Building torchvision with JPEG image support') | ||
image_link_flags.append('turbojpeg') | ||
if conda_installed: | ||
image_library += [turbo_lib_folder] | ||
image_include += [turbo_include_folder] | ||
|
||
image_path = os.path.join(extensions_dir, 'cpu', 'image') | ||
image_src = glob.glob(os.path.join(image_path, '*.cpp')) | ||
|
||
if png_found or turbojpeg_found: | ||
ext_modules.append(extension( | ||
'torchvision.image', | ||
image_src, | ||
include_dirs=include_dirs + [image_path] + image_include, | ||
library_dirs=library_dirs + image_library, | ||
define_macros=image_macros, | ||
libraries=image_link_flags, | ||
extra_compile_args=extra_compile_args | ||
)) | ||
|
||
ffmpeg_exe = distutils.spawn.find_executable('ffmpeg') | ||
has_ffmpeg = ffmpeg_exe is not None | ||
|
||
|
@@ -243,7 +372,9 @@ def run(self): | |
|
||
# Package info | ||
packages=find_packages(exclude=('test',)), | ||
|
||
package_data={ | ||
package_name: ['*.lib', '*.dylib', '*.so'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this necessary? We are able to package the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is necessary to pack libpng/turbojpeg into the wheel distributions |
||
}, | ||
zip_safe=False, | ||
install_requires=requirements, | ||
extras_require={ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it now safe to use
conda-forge
as well? At some point we had issues with it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems only libturbojpeg is being pulled from there, so all other packages are being pulled from defaults or the main PyTorch channel