SBU-BMI / wsinfer

🔥 🚀 Blazingly fast pipeline for patch-based classification in whole slide images
https://wsinfer.readthedocs.io
Apache License 2.0
56 stars 10 forks source link

[DIST] release wsinfer in a cross-platform manner without users creating environment #107

Closed kaczmarj closed 1 year ago

kaczmarj commented 1 year ago

look into pyinstaller or including a redistributable python environment with a release.

kaczmarj commented 1 year ago

we should probably go with pyinstaller because it seems like the most mature solution in this space. though torch jit is causing issues. see https://github.com/pyinstaller/pyinstaller/issues/5673 for a potential solution.

see https://github.com/pyinstaller/pyinstaller-hooks-contrib/issues/375#issuecomment-1025913127 regarding shared libraries not being found during build with pyinstaller.

kaczmarj commented 1 year ago

i got this to work with pyinstaller using the spec file below and this command:

pyinstaller wsinfer.spec

spec file:

# -*- mode: python ; coding: utf-8 -*-

import sys
from PyInstaller.utils.hooks import collect_all

sys.setrecursionlimit(sys.getrecursionlimit() * 5)

datas = []
binaries = []
hiddenimports = []
tmp_ret = collect_all('timm')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('wsinfer')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('tifftools')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('libtiff')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('large_image')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('PIL')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('large_image_source_tiff')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('large_image_source_openslide')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]

block_cipher = None

a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=binaries,
    datas=datas,
    hiddenimports=hiddenimports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

this wsinfer command worked:

./dist/wsinfer run --wsi-dir slides/ --results-dir foobar/ --model resnet34 --weights TCGA-BRCA-v1
kaczmarj commented 1 year ago

@swaradgat19 - this issue might be helpful when working on pyinstaller + wsinfer

kaczmarj commented 1 year ago

we're no longer planning to have this. but if anyone feels inspired to make a single executable for wsinfer, we'd welcome the contribution.