forked from compiler-research/xeus-clang-repl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dockerfile
346 lines (321 loc) · 15.6 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# https://hub.docker.com/r/jupyter/base-notebook/tags
ARG BASE_CONTAINER=jupyter/base-notebook
#ARG BASE_TAG=latest
ARG BASE_TAG=ubuntu-22.04
#TODO: Next ARG line(s) is temporary workaround.
# Remove them when we can build xeus-clang-repl with Xeus>=3.0
#ARG BASE_TAG=7285848c0a11
#ARG BASE_TAG=2023-01-24
#ENV VENV_PYTHON_VERSION=3.10.6
ARG BASE_TAG=python-3.10.6
FROM $BASE_CONTAINER:$BASE_TAG
ARG BUILD_TYPE=Release
LABEL maintainer="Xeus-clang-repl Project"
#LABEL com.nvidia.volumes.needed="nvidia_driver"
SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
USER root
ENV TAG="$BASE_TAG"
ENV LC_ALL=en_US.UTF-8 \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8
# Install all OS dependencies for notebook server that starts but lacks all
# features (e.g., download as all possible file formats)
RUN \
set -x && \
apt-get update --yes && \
apt-get install --yes --no-install-recommends pciutils && \
lspci && \
export _CUDA_="$(lspci -nn | grep '\[03' | grep NVIDIA)" && \
apt-get install --yes --no-install-recommends \
#fonts-liberation, pandoc, run-one are inherited from base-notebook container image
# Other "our" apt installs
unzip \
curl \
jq \
###libomp-dev \
# Other "our" apt installs (development and testing)
build-essential \
git \
nano-tiny \
less \
gdb valgrind \
emacs \
# CUDA
#cuda \
$([ -n "$_CUDA_" ] && echo nvidia-cuda-toolkit) \
&& \
apt-get clean && rm -rf /var/lib/apt/lists/* && \
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
ENV LC_ALL=en_US.UTF-8 \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8
# Create alternative for nano -> nano-tiny
#RUN update-alternatives --install /usr/bin/nano nano /bin/nano-tiny 10
USER ${NB_UID}
# Copy git repository to home directory of container
COPY --chown=${NB_UID}:${NB_GID} . "${HOME}"/
EXPOSE 8888 8889
# Configure container startup
CMD ["start-notebook.sh", "--debug", "&>/home/jovyan/log.txt"]
USER root
# Fix start-notebook.sh
RUN sed -i '2 i source /home/jovyan/.conda.init && conda activate .venv' /usr/local/bin/start-notebook.sh
# Make /home/runner directory and fix permisions
RUN mkdir /home/runner && fix-permissions /home/runner
# Switch back to jovyan to avoid accidental container runs as root
USER ${NB_UID}
ENV NB_PYTHON_PREFIX=${CONDA_DIR} \
KERNEL_PYTHON_PREFIX=${CONDA_DIR} \
CPLUS_INCLUDE_PATH="${CONDA_DIR}/include:/home/${NB_USER}/include:/home/runner/work/xeus-clang-repl/xeus-clang-repl/clang-dev/clang/include:/home/jovyan/clad/include:/home/jovyan/CppInterOp/include"
WORKDIR "${HOME}"
# CUDA
ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES=compute,utility
ENV NVIDIA_REQUIRE_CUDA "cuda>=12.1.1 driver>=530"
# VENV
# Jupyter Notebook, Lab, and Hub are installed in base image
# ReGenerate a notebook server config
# Cleanup temporary files
# Correct permissions
# Do all this in a single RUN command to avoid duplicating all of the
# files across image layers when the permissions change
#RUN mamba update --all --quiet --yes -c conda-forge && \
RUN \
set -x && \
# setup virtual environment
mamba create -y -n .venv python=3.10.6 && \
#
#echo "echo \"@ @ @ PROFILE @ @ @ \"" >> ~/.profile && \
#echo "echo \"@ @ @ BASHRC @ @ @ \"" >> /home/jovyan/.bashrc && \
mv /home/jovyan/.bashrc /home/jovyan/.bashrc.tmp && \
touch /home/jovyan/.bashrc && \
conda init bash && \
mv /home/jovyan/.bashrc /home/jovyan/.conda.init && \
mv /home/jovyan/.bashrc.tmp /home/jovyan/.bashrc && \
conda init bash && \
echo "source /home/jovyan/.conda.init && conda activate .venv" >> /home/jovyan/.bashrc && \
#
source /home/jovyan/.conda.init && \
conda activate .venv && \
fix-permissions "${CONDA_DIR}" && \
#
mamba install --quiet --yes -c conda-forge \
# notebook, jpyterhub, jupyterlab are inherited from base-notebook container image
# Other "our" conda installs
cmake \
#"clangdev=$LLVM_REQUIRED_VERSION" \
'xeus>=2.0,<3.0' \
'nlohmann_json>=3.9.1,<3.10' \
'cppzmq>=4.6.0,<5' \
'xtl>=0.7,<0.8' \
'openssl<2' \
ipykernel \
pugixml \
'cxxopts>=2.2.1,<2.3' \
libuuid \
# Test dependencies
pytest \
jupyter_kernel_test \
&& \
hash -r && \
pip install ipython && \
#rm /home/jovyan/.jupyter/jupyter_notebook_config.py && \
jupyter notebook --generate-config -y && \
mamba clean --all -f -y && \
npm cache clean --force && \
jupyter lab clean && \
rm -rf "/home/${NB_USER}/.cache/yarn" && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}"
### Post Build
RUN \
set -x && \
source /home/jovyan/.conda.init && \
conda activate .venv && \
#
artifact_name="clang-dev" && \
#
# Install clang-dev from GH Artifact or Release asset
#
echo $PWD && git_remote_origin_url=$(git config --get remote.origin.url) && \
echo "Debug: Remote origin url: $git_remote_origin_url" && \
arr=(${git_remote_origin_url//\// }) && \
gh_repo_owner=${arr[2]} && \
gh_f_repo_owner="compiler-research" && \
arr=(${arr[3]//./ }) && \
gh_repo_name=${arr[0]} && \
gh_repo="${gh_repo_owner}/${gh_repo_name}" && \
gh_f_repo_name=${gh_repo_name} && \
h=$(git rev-parse HEAD) && \
echo "Debug: Head h: $h" && \
br=$(git rev-parse --abbrev-ref HEAD) && \
echo "Debug: Branch br: $br" && \
#FIXME: if `$h` is not pushed upstream this fails. We should just diagnose and move on.
#git show-ref --head && echo $? && \
#git show-ref --head | grep "$h" && echo $? && \
#git show-ref --head | grep "$h" | grep -E "remotes|tags" && echo $? && \
#git show-ref --head | grep "$h" | grep -E "remotes|tags" | grep -o '[^/ ]*$' && echo $? && \
#arr1=$(git show-ref --head | grep "$h" | grep -E "remotes|tags" | grep -o '[^/ ]*$') && echo $? && \
arr1=$br && \
gh_repo_branch="${arr1[*]//\|}" && \
gh_repo_branch_regex=" ${gh_repo_branch//$'\n'/ | } " && \
gh_repo_branch_regex=$(echo "$gh_repo_branch_regex" | sed -e 's/[]\/$*.^[]/\\\\&/g') && \
echo "Debug: Repo Branch: $gh_repo_branch" && \
echo "Debug: Repo Branch Regex: $gh_repo_branch_regex" && \
mkdir -p /home/runner/work/xeus-clang-repl/xeus-clang-repl && \
pushd /home/runner/work/xeus-clang-repl/xeus-clang-repl && \
# repo
echo "Debug: Repo owner/name: ${gh_repo_owner} / ${gh_repo_name}" && \
#RUN \
# set -x && \
source /home/jovyan/.conda.init && \
conda activate .venv && \
repository_id=$(curl -s -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${gh_repo}" | jq -r ".id") && \
echo "Debug: Repo id: $repository_id" && \
artifacts_info=$(curl -s -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${gh_repo}/actions/artifacts?per_page=100&name=${artifact_name}") && \
artifact_id=$(echo "$artifacts_info" | jq -r "[.artifacts[] | select(.expired == false and .workflow_run.repository_id == ${repository_id} and (\" \"+.workflow_run.head_branch+\" \" | test(\"${gh_repo_branch_regex}\")))] | sort_by(.updated_at)[-1].id") && \
#download_url="https://nightly.link/${gh_repo_owner}/${gh_repo_name}/actions/artifacts/${artifact_id}.zip" && \
download_url="https://link-to.alexander-penev.info/${gh_repo_owner}/${gh_repo_name}/actions/artifacts/${artifact_id}.zip" && \
# forked repo
f_repository_id=$(curl -s -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${gh_f_repo_owner}/${gh_f_repo_name}" | jq -r ".id") && \
echo "Debug: Forked Repo id: $f_repository_id" && \
f_artifacts_info=$(curl -s -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${gh_f_repo_owner}/${gh_f_repo_name}/actions/artifacts?per_page=100&name=${artifact_name}") && \
f_artifact_id=$(echo "$f_artifacts_info" | jq -r "[.artifacts[] | select(.expired == false and .workflow_run.repository_id == ${f_repository_id} and (\" \"+.workflow_run.head_branch+\" \" | test(\"${gh_repo_branch_regex}\")))] | sort_by(.updated_at)[-1].id") && \
#f_download_url="https://nightly.link/${gh_f_repo_owner}/${gh_f_repo_name}/actions/artifacts/${f_artifact_id}.zip"
f_download_url="https://link-to.alexander-penev.info/${gh_f_repo_owner}/${gh_f_repo_name}/actions/artifacts/${f_artifact_id}.zip" && \
# tag
for download_tag in $gh_repo_branch; do echo "Debug: try tag $download_tag:"; download_tag_url="https://github.com/${gh_repo_owner}/${gh_repo_name}/releases/download/${download_tag}/${artifact_name}.tar.bz2"; if curl --head --silent --fail -L $download_tag_url 1>/dev/null; then echo "found"; break; fi; done && \
# try to download artifact ot release tag asset
echo "Debug: Download url (asset) repo info: $download_tag_url" && \
echo "Debug: Download url (artifact) repo info: $download_url" && \
echo "Debug: Download url (artifact) forked repo info: $f_download_url" && \
###
### clang-dev gihub only:
if curl --head --silent --fail -L "$download_tag_url" 1>/dev/null; then curl "$download_tag_url" -L -o "${artifact_name}.tar.bz2"; elif curl --head --silent --fail -L "$download_url" 1>/dev/null; then curl "$download_url" -L -o "${artifact_name}.zip"; else curl "$f_download_url" -L -o "${artifact_name}.zip"; fi && \
### clang-dev local archive only:
# mv /home/jovyan/"${artifact_name}.zip" ./&& \
###
if [[ -f "${artifact_name}.zip" ]]; then unzip "${artifact_name}.zip"; rm "${artifact_name}.zip"; fi && \
tar xjf ${artifact_name}.tar.bz2 && \
rm ${artifact_name}.tar.bz2 && \
cd $artifact_name && \
export PATH_TO_CLANG_DEV=$(pwd) && \
popd && \
#
echo "Debug clang path: $PATH_TO_CLANG_DEV" && \
export PATH_TO_LLVM_BUILD=$PATH_TO_CLANG_DEV/inst && \
export VENV=${CONDA_DIR}/envs/.venv && \
export PATH=${VENV}/bin:${CONDA_DIR}/bin:$PATH_TO_LLVM_BUILD/bin:$PATH && \
export LD_LIBRARY_PATH=$PATH_TO_LLVM_BUILD/lib:$LD_LIBRARY_PATH && \
echo "export VENV=$VENV" >> ~/.profile && \
echo "export PATH=$PATH" >> ~/.profile && \
echo "export EDITOR=emacs" >> ~/.profile && \
#
# Build CppInterOp
#
sys_incs=$(LC_ALL=C c++ -xc++ -E -v /dev/null 2>&1 | LC_ALL=C sed -ne '/starts here/,/End of/p' | LC_ALL=C sed '/^ /!d' | cut -c2- | tr '\n' ':') && \
export CPLUS_INCLUDE_PATH="${PATH_TO_LLVM_BUILD}/include/llvm:${PATH_TO_LLVM_BUILD}/include/clange:$CPLUS_INCLUDE_PATH:${sys_incs%:}" && \
git clone https://github.com/compiler-research/CppInterOp.git && \
export CB_PYTHON_DIR="$PWD/cppyy-backend/python" && \
export CPPINTEROP_DIR="$CB_PYTHON_DIR/cppyy_backend" && \
cd CppInterOp && \
mkdir build && \
cd build && \
export CPPINTEROP_BUILD_DIR=$PWD && \
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_CLING=OFF -DUSE_REPL=ON -DLLVM_DIR=$PATH_TO_LLVM_BUILD -DLLVM_USE_LINKER=gold -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR .. && \
cmake --build . --parallel $(nproc --all) && \
#make install -j$(nproc --all)
export CPLUS_INCLUDE_PATH="$CPPINTEROP_DIR/include:$CPLUS_INCLUDE_PATH" && \
export LD_LIBRARY_PATH="${VENV}/lib:${CONDA_DIR}/lib:$CPPINTEROP_DIR/lib:$LD_LIBRARY_PATH" && \
echo "export LD_LIBRARY_PATH=$CPPINTEROP_DIR/lib:$LD_LIBRARY_PATH" >> ~/.profile && \
cd ../.. && \
#
# Build and Install cppyy-backend
#
git clone https://github.com/compiler-research/cppyy-backend.git && \
cd cppyy-backend && \
mkdir -p $CPPINTEROP_DIR/lib build && cd build && \
# Install CppInterOp
(cd $CPPINTEROP_BUILD_DIR && cmake --build . --target install --parallel $(nproc --all)) && \
# Build and Install cppyy-backend
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCppInterOp_DIR=$CPPINTEROP_DIR .. && \
cmake --build . --parallel $(nproc --all) && \
cp libcppyy-backend.so $CPPINTEROP_DIR/lib/ && \
cd ../.. && \
#
# Build and Install CPyCppyy
#
# Install CPyCppyy
git clone https://github.com/compiler-research/CPyCppyy.git && \
cd CPyCppyy && \
mkdir build && cd build && \
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. && \
cmake --build . --parallel $(nproc --all) && \
export CPYCPPYY_DIR=$PWD && \
cd ../.. && \
#
# Build and Install cppyy
#
# Install cppyy
git clone https://github.com/compiler-research/cppyy.git && \
cd cppyy && \
python -m pip install --upgrade . --no-deps && \
cd .. && \
# Run cppyy
#TODO: Fix cppyy path (/home/jovyan) to path to installed module
export PYTHONPATH=$PYTHONPATH:$CPYCPPYY_DIR:$CB_PYTHON_DIR:/home/jovyan && \
echo "export PYTHONPATH=$PYTHONPATH" >> ~/.profile && \
export CPLUS_INCLUDE_PATH="/home/jovyan/CPyCppyy/include/:$CPLUS_INCLUDE_PATH" && \
# FIXME: Remove the hardcoded version of python here.
export CPLUS_INCLUDE_PATH="/home/jovyan/clad/include:$CPLUS_INCLUDE_PATH" && \
export CPLUS_INCLUDE_PATH="${VENV}/include:${VENV}/include/python3.10:$CPLUS_INCLUDE_PATH" && \
python -c "import cppyy" && \
#
# Build and Install xeus-clang-repl
#
mkdir build && \
cd build && \
echo "export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH" >> ~/.profile && \
##echo "conda activate .venv" >> ~/.profile
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DLLVM_CMAKE_DIR=$PATH_TO_LLVM_BUILD -DCMAKE_PREFIX_PATH=$KERNEL_PYTHON_PREFIX -DCMAKE_INSTALL_PREFIX=$KERNEL_PYTHON_PREFIX -DCMAKE_INSTALL_LIBDIR=lib -DLLVM_CONFIG_EXTRA_PATH_HINTS=${PATH_TO_LLVM_BUILD}/lib -DCPPINTEROP_DIR=$CPPINTEROP_BUILD_DIR -DLLVM_USE_LINKER=gold .. && \
make install -j$(nproc --all) && \
cd .. && \
#
# Build and Install Clad
#
git clone --depth=1 https://github.com/vgvassilev/clad.git && \
cd clad && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. -DClang_DIR=${PATH_TO_LLVM_BUILD}/lib/cmake/clang/ -DLLVM_DIR=${PATH_TO_LLVM_BUILD}/lib/cmake/llvm/ -DCMAKE_INSTALL_PREFIX=${CONDA_DIR} -DLLVM_EXTERNAL_LIT="$(which lit)" && \
#make -j$(nproc --all) && \
make && \
make install && \
### install clad in all exist kernels
##for i in "$KERNEL_PYTHON_PREFIX"/share/jupyter/kernels/*; do if [[ $i =~ .*/clad-xcpp.* ]]; then jq '.argv += ["-fplugin=$KERNEL_PYTHON_PREFIX/lib/clad.so"] | .display_name += " (with clad)"' "$i"/kernel.json > tmp.$$.json && mv tmp.$$.json "$i"/kernel.json; fi; done && \
###
### Add OpenMP to all kernels
###
##for i in "$KERNEL_PYTHON_PREFIX"/share/jupyter/kernels/*; do if [[ $i =~ .*/xcpp.* ]]; then jq '.argv += ["-fopenmp"] | .display_name += " (with OpenMP)"' "$i"/kernel.json > tmp.$$.json && mv tmp.$$.json "$i"/kernel.json; fi; done && \
#
# CUDA
#
#echo "c = get_config()" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
#echo "c.NotebookApp.notebook_manager_class = 'jupyter_gpu.GPUNotebookManager'" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
cat /home/jovyan/.jupyter/jupyter_notebook_config.py && \
echo "c.GPUNotebookManager.gpu_device = 0" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
# Web password and token set to ""
echo "c.NotebookApp.token = ''" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
echo "c.NotebookApp.password = ''" >> /home/jovyan/.jupyter/jupyter_notebook_config.py && \
# Patch /opt/conda/share/jupyter/kernels/python3/kernel.json to use .venv
k="/opt/conda/share/jupyter/kernels/python3/kernel.json" && \
jq ".argv[0] = \"${VENV}/bin/python\"" $k > $k.$$.tmp && mv $k.$$.tmp $k && \
# xtensor
git clone https://github.com/xtensor-stack/xtensor.git && \
cd xtensor && \
mkdir build && cd build && \
cmake -DCMAKE_INSTALL_PREFIX=$KERNEL_PYTHON_PREFIX .. && \
make install