{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# [TSUBAME3特有] Jupyter Lab 機能で CuPy を使うには\n",
"TSUBAME3のJuputer Lab機能で提供されるPythonにはデフォルトではCuPyが含まれていません。 \n",
"CuPyの利用には、CUDA関係の環境変数の設定など、いくつか前準備が必要になるため、ここでは順を追って例を示します。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CUDA等が利用できるJupyter Kernelを用意する\n",
"TSUBAME3のJupyter Lab機能には、任意のモジュールがロードされた状態のPython環境(Kernel)を設定する機能が提供されています。 \n",
"CUDA, CuDNN, NCCLが利用できるカーネルを作成するには、以下のコードを実行してください。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"finished : The kernel is ready.\n"
]
}
],
"source": [
"from t3jpttools import create_kernel\n",
"create_kernel('python3-cuda','cuda/10.2.89 cudnn/7.6 nccl/2.4.2')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"登録されているカーネルの一覧は以下のコードで得られます"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Available kernels:\n",
"------------------------------\n",
"python3-cuda\n",
"python3\n",
"------------------------------\n",
"finished : Listed kernels.\n"
]
}
],
"source": [
"from t3jpttools import list_kernel, delete_kernel, create_kernel\n",
"list_kernel()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"登録したカーネルは以下のコマンドで削除できます。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"finished : The kernel is deleted.\n"
]
}
],
"source": [
"from t3jpttools import delete_kernel\n",
"delete_kernel('python3-cuda')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"create_kernel()を実行後、数十秒待つと、右上のカーネル選択メニューに作成したカーネルが出現します。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ここから先は、作成したカーネルを選択してから実行してください。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CuPy のインストール\n",
"CuPyのインストールは`pip`コマンドを実行することで行えます。 \n",
"時間短縮のためにも`cupy`パッケージではなく、`cupy-cuda102` など、CUDAバージョンを明示的に指定したパッケージをインストールしてください。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Collecting cupy-cuda102\n",
" Downloading cupy_cuda102-7.4.0-cp36-cp36m-manylinux1_x86_64.whl (380.4 MB)\n",
"Collecting matplotlib\n",
" Downloading matplotlib-3.2.1-cp36-cp36m-manylinux1_x86_64.whl (12.4 MB)\n",
"Collecting fastrlock>=0.3\n",
" Downloading fastrlock-0.4-cp36-cp36m-manylinux1_x86_64.whl (31 kB)\n",
"Collecting numpy>=1.9.0\n",
" Downloading numpy-1.18.3-cp36-cp36m-manylinux1_x86_64.whl (20.2 MB)\n",
"Requirement already satisfied: six>=1.9.0 in /apps/t3/sles12sp4/free/jupyterlab/2.1.0/gcc4.8.5/lib/python3.6/site-packages (from cupy-cuda102) (1.14.0)\n",
"Collecting cycler>=0.10\n",
" Downloading cycler-0.10.0-py2.py3-none-any.whl (6.5 kB)\n",
"Collecting pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1\n",
" Downloading pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)\n",
"Collecting kiwisolver>=1.0.1\n",
" Downloading kiwisolver-1.2.0-cp36-cp36m-manylinux1_x86_64.whl (88 kB)\n",
"Requirement already satisfied: python-dateutil>=2.1 in /apps/t3/sles12sp4/free/jupyterlab/2.1.0/gcc4.8.5/lib/python3.6/site-packages (from matplotlib) (2.8.1)\n",
"Installing collected packages: fastrlock, numpy, cupy-cuda102, cycler, pyparsing, kiwisolver, matplotlib\n",
"Successfully installed cupy-cuda102-7.4.0 cycler-0.10.0 fastrlock-0.4 kiwisolver-1.2.0 matplotlib-3.2.1 numpy-1.18.3 pyparsing-2.4.7\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
" WARNING: The scripts f2py, f2py3 and f2py3.6 are installed in '/home/1/nomura-a-ac/.local/bin' which is not on PATH.\n",
" Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.\n"
]
}
],
"source": [
"%%bash\n",
"python3 -m pip install --user cupy-cuda102 matplotlib"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"CuPyのインストールが終わったら、先ほどと同様の手順で同じカーネルを選択し直すか、0を2回タイプして、Pythonをリロードしてください。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CuPyの利用\n",
"あとは、通常の CuPy がインストールされた環境と同様、cupy モジュールが利用できるようになります。 \n",
"CUDAが利用できるカーネルが選択されていれば、次回以降はカーネルやCuPyのインストールを行う必要はありません。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"