Installing Prophet on CentOS

I’ve been struggling to get the {prophet} package to install on two RHEL 7 systems. Since I only have intermittent access to those systems I opted to use a local install of CentOS as a proxy environment. These instructions work for CentOS and should generalise to RHEL too.

Logo of Prophet.

Setting Up the Environment

The first thing that I needed to do was create an environment for testing. I actually tried two options: VirtualBox and Docker.

VirtualBox

Download the DVD ISO or Everything ISO from either of these sources:

Install the ISO on VirtualBox. Launch the image and login.

Docker

docker pull centos:7.8.2003
docker run -it centos:7.8.2003 /bin/bash

Install R & Python

First install R and Python 3.

sudo yum update
sudo yum install -y epel-release
sudo yum install -y R python3 python3-devel

💡 If you’re using the Docker image (or logged in as root) then you don’t need to prefix commands with sudo.

Updating Compiler

It really can’t hurt to have an upgraded compiler, right?

You’ll find that most R packages will install smoothly simply using install.packages(). Not so with the prophet package though. The problem is that this package requires a compiler which supports the C++14 standard. The default compiler which comes bundled with CentOS 7, gcc 4.8.5, does not support the C++14 standard.

The first thing that you need to do is get a new compiler by installing another SCL (Software Collection).

sudo yum install -y centos-release-scl
sudo yum install -y devtoolset-8

Now activate the SCL and check the compiler version.

scl enable devtoolset-8 bash
gcc --version

You should now have gcc 8.3.1.

You’ll probably want to use this compiler by default now. You can automatically enable the SCL at login by adding the following line to your ~/.bash_profile:

. /opt/rh/devtoolset-8/enable

Installing Prophet for R

Now you can launch R and start installing packages. If you run into issues with certificates (I did!) you can do the following:

options(repos = c(CRAN = "http://cran.rstudio.com/"))

Check on the location of g++.

which g++
/opt/rh/devtoolset-8/root/usr/bin/g++

Create a ~/.R/Makevars file with the following content:

CXX14=/opt/rh/devtoolset-8/root/usr/bin/g++
CXX14FLAGS=-O3 -march=native -mtune=native -fPIC

Update the value of CXX14 if the location of the compiler differs on your system.

Now start R. We’ll install {rstan} first.

install.packages("rstan")

Once the install is finished you can do a quick test (thanks Ben Letham!) to verify that it works.

library(rstan)
fit <- stan(model_code = 'parameters {real y;} model {y ~ normal(0,1);}')
mean(extract(fit)$y)
#
# Result should be close to 0.

Once {rstan} is working, we’ll move onto {prophet}.

install.packages("prophet")

You might get an error like this (probably on RHEL but not on CentOS):

Error in dyn.load(libLFile) :
  unable to load shared object '/tmp/RtmpKZb6vU/file158135f4cea.so':
  /tmp/RtmpKZb6vU/file158135f4cea.so: failed to map segment from shared object: Operation not permitted

This indicates a permission problem on /tmp. I investigated and found:

df -h
Filesystem                          Size  Used Avail Use% Mounted on
/dev/mapper/vg_00-lv_root            15G  4.0G   11G  28% /
devtmpfs                             32G     0   32G   0% /dev
tmpfs                                32G     0   32G   0% /dev/shm
tmpfs                                32G  3.2G   29G  11% /run
tmpfs                                32G     0   32G   0% /sys/fs/cgroup
/dev/sda1                           497M  209M  289M  42% /boot
/dev/mapper/vg_00-lv_home           2.4G  1.2G  1.3G  49% /home
/dev/mapper/vg_00-lv_var            8.3G  979M  7.3G  12% /var
/dev/mapper/vg_00-lv_tmp            473M   25M  449M   6% /tmp
/dev/mapper/vg_00-lv_var_tmp        473M   25M  449M   6% /var/tmp
/dev/mapper/vg_00-lv_var_log        4.7G  1.1G  3.6G  23% /var/log
/dev/mapper/vg_00-lv_var_log_audit  473M   55M  419M  12% /var/log/audit
tmpfs                               6.3G     0  6.3G   0% /run/user/0

Remounting /tmp did the trick.

sudo mount /tmp -o remount,exec

Unfortunately this change will disappear on reboot. You can make it permanent by editing /etc/fstab and changing

/dev/mapper/vg_00-lv_tmp /tmp xfs nodev,nosuid,noexec 0 0

to

/dev/mapper/vg_00-lv_tmp /tmp xfs nodev,nosuid,exec 0 0

This should get {prophet} installed. I’d be super interested to know if there’s an alternative (simpler!) approach to getting this working or if anybody encounters other installation issues.

Epilogue

Somewhat weirdly I had to repeat the installation on the same system and the recipe above failed to work. Here’s another option.

Download specific versions of {StanHeaders} and {rstan}.

wget https://cran.r-project.org/src/contrib/Archive/StanHeaders/StanHeaders_2.18.0.tar.gz
wget https://cran.r-project.org/src/contrib/Archive/rstan/rstan_2.18.1.tar.gz

Install from the command line.

R CMD INSTALL StanHeaders_2.18.0.tar.gz
R CMD INSTALL rstan_2.18.1.tar.gz

Now install {prophet} from inside R.

Installing Prophet for Python

Ensure that we have a suitable locale.

export LC_CTYPE=en_US.UTF-8
export LANG=en_US.UTF-8

Now install the prophet package (and optionally the plotly package).

pip3 install prophet
# If you want to use Plotly with Prophet.
pip3 install plotly

Crank up Python and load the prophet package.

import prophet

Bam! 🚀