Skip to content

Download correct CmdStan tarball on non-x86 linux #616

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

Merged
merged 5 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions cmdstanpy/install_cmdstan.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
validate_dir,
wrap_url_progress_hook,
)
from cmdstanpy.utils.cmdstan import get_download_url

from . import progress as progbar

Expand Down Expand Up @@ -426,10 +427,7 @@ def install_version(

def is_version_available(version: str) -> bool:
is_available = True
url = (
'https://github.com/stan-dev/cmdstan/releases/download/'
'v{0}/cmdstan-{0}.tar.gz'.format(version)
)
url = get_download_url(version)
for i in range(6):
try:
urllib.request.urlopen(url)
Expand Down Expand Up @@ -458,10 +456,7 @@ def retrieve_version(version: str, progress: bool = True) -> None:
if version is None or version == '':
raise ValueError('Argument "version" unspecified.')
print('Downloading CmdStan version {}'.format(version))
url = (
'https://github.com/stan-dev/cmdstan/releases/download/'
'v{0}/cmdstan-{0}.tar.gz'.format(version)
)
url = get_download_url(version)
for i in range(6): # always retry to allow for transient URLErrors
try:
if progress and progbar.allow_show_progress():
Expand Down
39 changes: 39 additions & 0 deletions cmdstanpy/utils/cmdstan.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
import os
import platform
import subprocess
import sys
from collections import OrderedDict
from typing import Callable, Dict, Optional, Tuple, Union
Expand All @@ -17,6 +18,44 @@
EXTENSION = '.exe' if platform.system() == 'Windows' else ''


def determine_linux_arch() -> str:
machine = platform.machine()
arch = ""
if machine == "aarch64":
arch = "arm64"
elif machine == "armv7l":
# Telling armel and armhf apart is nontrivial
# c.f. https://forums.raspberrypi.com/viewtopic.php?t=20873
if subprocess.run(
["readelf -A /proc/self/exe | grep Tag_ABI_VFP_args"],
shell=True,
check=False,
).returncode:
arch = "armel"
else:
arch = "armhf"
elif machine == "mips64":
arch = "mips64el"
elif machine == "ppc64el":
arch = "ppc64le"
elif machine == "s390x":
arch = "s390x"
return arch


def get_download_url(version: str) -> str:
arch = os.environ.get("CMDSTAN_ARCH", "")
if not arch and platform.system() == "Linux":
arch = determine_linux_arch()

if arch and arch.lower() != "false":
url_end = f'v{version}/cmdstan-{version}-linux-{arch}.tar.gz'
else:
url_end = f'v{version}/cmdstan-{version}.tar.gz'

return f'https://github.com/stan-dev/cmdstan/releases/download/{url_end}'


def validate_dir(install_dir: str) -> None:
"""Check that specified install directory exists, can write."""
if not os.path.exists(install_dir):
Expand Down
11 changes: 11 additions & 0 deletions docsrc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ can be used to override these defaults:
install_cmdstan -d my_local_cmdstan -v 2.27.0
ls -F my_local_cmdstan

Alternate Linux Architectures
.............................

CmdStan can be installed on Linux for the following non-x86 architectures:
``arm64``, ``armel``, ``armhf``, ``mips64el``, ``ppc64el`` and ``s390x``.

CmdStanPy will do its best to determine which of these is applicable for your
machine when running ``install_cmdstan``. If the wrong choice is made, or if you
need to manually override this, you can set the ``CMDSTAN_ARCH`` environment variable
to one of the above options, or to "false" to use the standard x86 download.

DIY Installation
^^^^^^^^^^^^^^^^

Expand Down