3. Setting up and Using Development Tools

3.1. Overview

This tutorial introduces users to modern development tools and workflows that simplify working on HPC systems like Cyclone. Participants will learn to set up and configure tools like VS Code and MobaXTerm for remote file editing and code management directly on Cyclone. The session also covers how to use the module system to load software environments and how to extend functionality with tools like Conda or virtual environments (venv). By adopting these workflows, users will enhance their productivity and streamline their interactions with Cyclone.

3.2. Learning Objectives

By the end of this tutorial, participants will be able to:
  1. Set up and configure modern development tools, such as VS Code (for all platforms) or MobaXTerm (for Windows), to remotely access Cyclone and edit files directly on the system.
  2. Understand how to use Cyclone’s module system to load and manage software environments.
  3. Create and manage custom environments using tools like Conda or virtual environments (venv) to extend functionality and accommodate specific project needs.

3.3. Prerequisites

  1. T01 - Introduction to HPC Systems: This tutorial will give you some basic knowledge on HPC systems and basic terminologies.

  2. T02 - Accessing and Navigating Cyclone:This tutorial will give you some basic knowledge on how to connect, copy files and navigate the HPC system.


3.4. Tools for development

In this section we will cover how to setup VS Code and MobaXTerm, so the user can connect to Cyclone, and start developing.

3.4.1. VS Code

Visual Studio Code (VS Code) is a versatile code editor widely used for software development. With the Remote - SSH extension, it enables seamless connection to Cyclone, allowing users to edit, debug, and manage code directly on the HPC system. This eliminates the need for constant file transfers and provides a familiar development environment. By using VS Code, developers can streamline workflows and enhance productivity on Cyclone.

Setting up VS Code

Users should follow this link, and download the appropriate VS Code installer based on their OS. Then, follow the on-screen instuctions during the installation.
Once the installation is finished, it is time to install some basic extensions. Depending on your code-base, you might want to install some code extensions such as Python. Furthermore, there are various extensions that provide extended support for code predictions or auto-completions. Feel free to browse the Extension Marketplace and download the ones you need!
The only extension that is 100% mandatory for this tutorial is the Remote-SSH extension. Remote-SSH enables you to use any remote machine with an SSH server as your development environment.
Go ahead and search Remote - SSH in the Extension Marketplace and install it.

alt text

After you install the extension, you will see an extra button on the left side-panel and on the bottom left. If you don't, restart VS Code.

alt text

When you click the extension's button, you might see on the top right of the panel a drop-down menu. Remote-ssh lets you connect to other systems as well, such as docker. For our use-case, we need to select the Remotes (Tunnels/SSH) option if it's not already selected

alt text

Connecting to Cyclone

Now that we have Remote-SSH installed, it's time to set it up so it can establish a connection on Cyclone.
If you followed the tutorials up until this point, you should have a private ssh key and a config file that lets you connect onto Cyclone through your terminal. We are going to use both to let VS Code connect onto Cyclone as well.
⚠️ If not, please refer to Tutorial 2 for instructions on how to set this up.
First, go and add the following lines to your ssh config file. The config file is located at:
Windows: %userprofile%/.ssh/

Linux & Mac: ~/.ssh/
Your SSH config file should get picked up by VS Code. You should see an option called cyclone on the left panel when you press the extension's button.

alt text

When you hover over that option, you will see two buttons on the right:
  • The first button will establish a connection on your current VS Code window
  • The second button will open a new VS Code window and establish a connection on that
Go ahead and click the first button.
ℹ️ You might get a prompt to select the hosts (Cyclone) operating system. Go ahead and select Linux.
After that, if everything is setup correctly, you will get a prompt asking for a passphrase. Go ahead and type your passphrase and press enter.
That's it - you are now connected on Cyclone with VS Code!! The explorer bar on VS Studio should now look as below:

alt text

Note: Do not click Open Folder yet.
If you followed this tutorial series up to this point, you should be familiar on how Cyclone's file system is structured.
Just to remind you, Cyclone has 3 different directory types:
  • $HOME (/nvme/h/<username>): is the home directory of a user. Users should store their source code and build executables here. The home directory is limited in size.

  • $DATA_<projectid> (/nvme/h/<username>/data_<projectid>): is the data directory of a user within the project shared directory. Users must change to this directory in their batch scripts to run their jobs. The data directory has a total maximum quota as allocated to each project.

  • $SCRATCH (/nvme/scratch/<username>): is a temporary storage directory for data to reside. Month old contents of scratch directory are purged during the monthly maintenance windows.
At the end of this tutorial, we are going to have a hands-on session, where we will use everything that we will learn. For this purpose, we are going to create a folder for our dummy project in our $HOME directory.
Open VS Code's terminal or your prefered one. Then go into your $HOME directory and create a folder by typing:
cd $HOME
mkdir tutorial_03_project
ls -l
The ls -l command should show our newly created folder.
Now click Open Folder, and select the folder that we just created. You will be prompted to insert your passphrase once more. After that, you will be able to see that folder on the left panel, when you click the remote-ssh extension button:

alt text

From now on, you will be able to establish a remote-ssh connection straight to that folder.

3.4.2. MobaXTerm

MobaXTerm is an all-in-one remote desktop and terminal solution designed for developers and system administrators. It provides a user-friendly interface for SSH connections, enabling easy access to Cyclone's HPC environment. With features like remote file editing, a built-in SFTP browser, and X11 forwarding, users can manage files, run graphical applications, and execute commands efficiently. MobaXTerm simplifies remote workflows, making it an excellent tool for working on Cyclone.

Setting up MobaXTerm (Windows Only)

  1. Go to this URL, and download MobaXTerm.
  2. After you download the zip folder, extract it, and run the .msi file located inside the folder. If you download the portable edition, then just double click the downloaded file and it will open the application straight away.
  3. Follow the installer's steps until completion. Keep in mind, Administrative permission is required to install this software.
  4. Go ahead and launch the software. You might be prompted to allow MobaXTerm to access private networks, click allow.

alt text

Launching an SSH session on MobaXTerm
There's a button on the top left corner called Session. Click that, and then select the first option that reads SSH.

alt text

Afterwards, fill the Remote Host (cyclone.hpcf.cyi.ac.cy), click Specify username and type your username.

alt text

Lastly, we have to setup our SSH key. Click on Advanced SSH settings, then click Use Private Key, and then write the path of your private key for Cyclone.

alt text

Click OK, you will then be prompted to insert your Passphrase.
After that you are done! You have an established connection to Cyclone with MobaXTerm.

alt text

This tool is very versitile and has a lot of functionality. Please visit their documentation page to read more about it.

3.5. Using Cyclone's Module System

The OS of Cyclone is a minimal Linux installation. Software applications installed on the Cyclone, are available through the Module system.
ℹ️ For basic overview of the Module system please refer at T01 - Introduction to HPC Systems.

3.5.1. Finding a Module

There are two ways to search for modules:
module avail
module spider
The module avail command returns the names of all available modules. If you are a new user, it is recommended to use this command.
ℹ️ Some modules have the (D) next to them. This means they are the default module to be loaded when a version is not specified
[marconstantinou@front02 ~]$ module avail

---------------------------------------------------------------------- /eb/modules/all ----------------------------------------------------------------------
   4ti2/1.6.10-GCC-13.2.0                                                XZ/5.4.5-GCCcore-13.3.0                        (D)
   ABAQUS/2024                                                           Xerces-C++/3.2.4-GCCcore-12.3.0
   ANTLR/2.7.7-GCCcore-8.3.0-Java-11                                     Xvfb/21.1.3-GCCcore-11.3.0
   ASE/3.22.1-foss-2022a                                                 YACS/0.1.8-GCCcore-11.3.0
   ATK/2.38.0-GCCcore-11.3.0                                             Yasm/1.3.0-GCCcore-11.2.0
   Abseil/20230125.3-GCCcore-12.3.0                                      Yasm/1.3.0-GCCcore-11.3.0
   AmberTools/22.3-foss-2021b                                            Yasm/1.3.0-GCCcore-12.3.0
   AmberTools/22.3-foss-2022a                                    (D)     Yasm/1.3.0-GCCcore-13.2.0                      (D)
   Anaconda3/2021.11                                                     Z3/4.10.2-GCCcore-11.3.0
   Anaconda3/2023.03-1                                           (D)     Z3/4.12.2-GCCcore-12.3.0                       (D)
   ...
   XZ/5.2.5-GCCcore-11.2.0                                               zstd/1.5.0-GCCcore-11.2.0
   XZ/5.2.5-GCCcore-11.3.0                                       (L)     zstd/1.5.2-GCCcore-11.3.0
   XZ/5.2.7-GCCcore-12.2.0                                               zstd/1.5.2-GCCcore-12.2.0
   XZ/5.4.2-GCCcore-12.3.0                                               zstd/1.5.5-GCCcore-12.3.0
   XZ/5.4.4-GCCcore-13.2.0                                               zstd/1.5.5-GCCcore-13.2.0                      (D)

  Where:
   Aliases:  Aliases exist: foo/1.2.3 (1.2) means that "module load foo/1.2" will load foo/1.2.3
   D:        Default Module
   L:        Module is loaded

If the avail list is too long consider trying:

"module --default avail" or "ml -d av" to just list the default modules.
"module overview" or "ml ov" to display the number of modules for each name.

Use "module spider" to find all possible modules and extensions.
Use "module keyword key1 key2 ..." to search for all possible modules matching any of the "keys".
The module spider command shows a lot more information about the modules. Users can use the avail command to find the exact name of the module they are looking for, and then use the spider command on the exact name, to find more information about it
[marconstantinou@front02 ~]$ module spider

---------------------------------------------------------------------------------------------------------------------------------------------------------
The following is a list of the modules and extensions currently available:
---------------------------------------------------------------------------------------------------------------------------------------------------------
  4ti2: 4ti2/1.6.10-GCC-13.2.0
    A software package for algebraic, geometric and combinatorial problems on linear spaces

  ABAQUS: ABAQUS/2024
    Finite Element Analysis software for modeling, visualization and best-in-class implicit and explicit dynamics FEA.

  ANTLR: ANTLR/2.7.7-GCCcore-8.3.0-Java-11
    ANTLR, ANother Tool for Language Recognition, (formerly PCCTS) is a language tool that provides a framework for constructing recognizers, compilers,
    and translators from grammatical descriptions containing Java, C#, C++, or Python actions.

  ASE: ASE/3.22.1-foss-2022a
    ASE is a python package providing an open source Atomic Simulation Environment in the Python scripting language. From version 3.20.1 we also include
    the ase-ext package, it contains optional reimplementations in C of functions in ASE. ASE uses it automatically when installed.

  ATK: ATK/2.38.0-GCCcore-11.3.0
    ATK provides the set of accessibility interfaces that are implemented by other toolkits and applications. Using the ATK interfaces, accessibility
    tools have full access to view and control running applications. 

  ...

  zlib: zlib/1.2.8, zlib/1.2.11-GCCcore-8.3.0, zlib/1.2.11-GCCcore-10.2.0, zlib/1.2.11-GCCcore-11.2.0, zlib/1.2.11, zlib/1.2.12-GCCcore-11.3.0, ...
    zlib is designed to be a free, general-purpose, legally unencumbered -- that is, not covered by any patents -- lossless data-compression library for
    use on virtually any computer hardware and operating system.

  zstd: zstd/1.5.0-GCCcore-11.2.0, zstd/1.5.2-GCCcore-11.3.0, zstd/1.5.2-GCCcore-12.2.0, zstd/1.5.5-GCCcore-12.3.0, zstd/1.5.5-GCCcore-13.2.0
    Zstandard is a real-time compression algorithm, providing high compression ratios. It offers a very wide range of compression/speed trade-off, while
    being backed by a very fast decoder. It also offers a special mode for small data, called dictionary compression, and can create dictionaries from
    any sample set.

---------------------------------------------------------------------------------------------------------------------------------------------------------

To learn more about a package execute:

   $ module spider Foo

where "Foo" is the name of a module.

To find detailed information about a particular package you
must specify the version if there is more than one version:

   $ module spider Foo/11.1

---------------------------------------------------------------------------------------------------------------------------------------------------------
If we want to search more details about a specific package, such as Python v.3.10.8, then we can do so as follows:
[marconstantinou@front02 ~]$ module spider Python/3.10.8-GCCcore-12.2.0

---------------------------------------------------------------------------------------------------------------------------------------------------------
  Python: Python/3.10.8-GCCcore-12.2.0
---------------------------------------------------------------------------------------------------------------------------------------------------------
    Description:
      Python is a programming language that lets you work more quickly and integrate your systems more effectively.


    This module can be loaded directly: module load Python/3.10.8-GCCcore-12.2.0

    Help:

      Description
      ===========
      Python is a programming language that lets you work more quickly and integrate your systems
       more effectively.


      More information
      ================
       - Homepage: https://python.org/


      Included extensions
      ===================
      alabaster-0.7.12, appdirs-1.4.4, asn1crypto-1.5.1, atomicwrites-1.4.1,
      attrs-22.1.0, Babel-2.11.0, backports.entry-points-selectable-1.2.0,
      backports.functools_lru_cache-1.6.4, bcrypt-4.0.1, bitstring-3.1.9,
      blist-1.3.6, CacheControl-0.12.11, cachy-0.3.0, certifi-2022.9.24,
      cffi-1.15.1, chardet-5.0.0, charset-normalizer-2.1.1, cleo-1.0.0a5,
      click-8.1.3, clikit-0.6.2, colorama-0.4.6, crashtest-0.3.1,
      cryptography-38.0.3, Cython-0.29.32, decorator-5.1.1, distlib-0.3.6,
      docopt-0.6.2, docutils-0.19, dulwich-0.20.50, ecdsa-0.18.0, editables-0.3,
      exceptiongroup-1.0.1, filelock-3.8.0, flit-3.8.0, flit_core-3.8.0,
      flit_scm-1.7.0, fsspec-2022.11.0, future-0.18.2, glob2-0.7,
      hatch_fancy_pypi_readme-22.8.0, hatch_vcs-0.2.0, hatchling-1.11.1,
      html5lib-1.1, idna-3.4, imagesize-1.4.1, importlib_metadata-5.0.0,
      importlib_resources-5.10.0, iniconfig-1.1.1, intervaltree-3.1.0,
      intreehooks-1.0, ipaddress-1.0.23, jaraco.classes-3.2.3, jeepney-0.8.0,
      Jinja2-3.1.2, joblib-1.2.0, jsonschema-4.17.0, keyring-23.11.0,
      keyrings.alt-4.2.0, liac-arff-2.5.0, lockfile-0.12.2, MarkupSafe-2.1.1,
      mock-4.0.3, more-itertools-9.0.0, msgpack-1.0.4, netaddr-0.8.0,
      netifaces-0.11.0, packaging-21.3, paramiko-2.12.0, pastel-0.2.1,
      pathlib2-2.3.7.post1, pathspec-0.10.1, pbr-5.11.0, pexpect-4.8.0, pip-22.3.1,
      pkginfo-1.8.3, platformdirs-2.5.3, pluggy-1.0.0, poetry-1.2.2, poetry-
      core-1.3.2, poetry_plugin_export-1.2.0, psutil-5.9.4, ptyprocess-0.7.0,
      py-1.11.0, py_expression_eval-0.3.14, pyasn1-0.4.8, pycparser-2.21,
      pycrypto-2.6.1, Pygments-2.13.0, pylev-1.4.0, PyNaCl-1.5.0, pyparsing-3.0.9,
      pyrsistent-0.19.2, pytest-7.2.0, python-dateutil-2.8.2, pytoml-0.1.21,
      pytz-2022.6, regex-2022.10.31, requests-2.28.1, requests-toolbelt-0.9.1,
      scandir-1.10.0, SecretStorage-3.3.3, semantic_version-2.10.0,
      setuptools-63.4.3, setuptools-rust-1.5.2, setuptools_scm-7.0.5,
      shellingham-1.5.0, simplegeneric-0.8.1, simplejson-3.17.6, six-1.16.0,
      snowballstemmer-2.2.0, sortedcontainers-2.4.0, Sphinx-5.3.0, sphinx-bootstrap-
      theme-0.8.1, sphinxcontrib-applehelp-1.0.2, sphinxcontrib-devhelp-1.0.2,
      sphinxcontrib-htmlhelp-2.0.0, sphinxcontrib-jsmath-1.0.1, sphinxcontrib-
      qthelp-1.0.3, sphinxcontrib-serializinghtml-1.1.5, sphinxcontrib-
      websupport-1.2.4, tabulate-0.9.0, threadpoolctl-3.1.0, toml-0.10.2,
      tomli-2.0.1, tomli_w-1.0.0, tomlkit-0.11.6, typing_extensions-4.4.0,
      ujson-5.5.0, urllib3-1.26.12, virtualenv-20.16.6, wcwidth-0.2.5,
      webencodings-0.5.1, wheel-0.38.4, xlrd-2.0.1, zipfile36-0.1.3, zipp-3.10.0

3.5.2. Managing Modules

Loading a Module

By using module load $MODULE_NAME you can load and use $MODULE_NAME.
Example: Using Python v3.10.4 instead of system default (v3.10.13)
[marconstantinou@front02 ~]$ python -V # Check if Python is loaded
Python 3.10.13 # Python v3.10.13 is loaded by default
[marconstantinou@front02 ~]$ module avail python # This will print all available python modules
------------------------------- /eb/modules/all --------------------------------
   ...
   Python/2.7.16-GCCcore-8.3.0
   Python/2.7.18-GCCcore-11.2.0-bare
   Python/2.7.18-GCCcore-11.2.0
   Python/3.7.4-GCCcore-8.3.0
   Python/3.8.6-GCCcore-10.2.0
   Python/3.9.6-GCCcore-11.2.0-bare
   Python/3.9.6-GCCcore-11.2.0
   Python/3.10.4-GCCcore-11.3.0-bare
   Python/3.10.4-GCCcore-11.3.0
   Python/3.10.8-GCCcore-12.2.0-bare
   Python/3.10.8-GCCcore-12.2.0
   Python/3.11.3-GCCcore-12.3.0
   Python/3.11.5-GCCcore-13.2.0
   Python/3.12.3-GCCcore-13.3.0                            (D)
   ...

  Where:
   D:  Default Module

If the avail list is too long consider trying:

"module --default avail" or "ml -d av" to just list the default modules.
"module overview" or "ml ov" to display the number of modules for each name.

Use "module spider" to find all possible modules and extensions.
Use "module keyword key1 key2 ..." to search for all possible modules matching
any of the "keys".
[marconstantinou@front02 ~]$ module load Python/3.10.4-GCCcore-11.3.0 # Load Python 3.10.4
[marconstantinou@front02 ~]$ python -V
Python 3.10.4

Checking Loaded Modules

To see what modules are already loaded and used in your environment, we can type:
module list
[marconstantinou@front02 ~]$ module list

Currently Loaded Modules:
  1) GCCcore/11.3.0                 5) ncurses/6.3-GCCcore-11.3.0         9) XZ/5.2.5-GCCcore-11.3.0      13) Python/3.10.4-GCCcore-11.3.0
  2) zlib/1.2.12-GCCcore-11.3.0     6) libreadline/8.1.2-GCCcore-11.3.0  10) GMP/6.2.1-GCCcore-11.3.0
  3) binutils/2.38-GCCcore-11.3.0   7) Tcl/8.6.12-GCCcore-11.3.0         11) libffi/3.4.2-GCCcore-11.3.0
  4) bzip2/1.0.8-GCCcore-11.3.0     8) SQLite/3.38.3-GCCcore-11.3.0      12) OpenSSL/1.1
This will show the currently loaded modules. Note here we also see Python/3.10.4-GCCcore-11.3.0 being available (along with any dependencies), following the previous example.

Unload a Module

Following the previous example, to unload the loaded Python version, we can do so by using the module unload command. This will remove the specified module from the loaded modules of your environment.
Example: Removing Python 3.10.4 From the Environment
[marconstantinou@front02 ~]$ module unload Python/3.10.4-GCCcore-11.3.0
[marconstantinou@front02 ~]$ module list

Currently Loaded Modules:
  1) GCCcore/11.3.0                 4) bzip2/1.0.8-GCCcore-11.3.0         7) Tcl/8.6.12-GCCcore-11.3.0     10) GMP/6.2.1-GCCcore-11.3.0
  2) zlib/1.2.12-GCCcore-11.3.0     5) ncurses/6.3-GCCcore-11.3.0         8) SQLite/3.38.3-GCCcore-11.3.0  11) libffi/3.4.2-GCCcore-11.3.0
  3) binutils/2.38-GCCcore-11.3.0   6) libreadline/8.1.2-GCCcore-11.3.0   9) XZ/5.2.5-GCCcore-11.3.0       12) OpenSSL/1.1
[marconstantinou@front02 ~]$ python -V
Python 3.10.13
You can also switch from one version to another in one go via module swap:
[marconstantinou@front02 ~]$ module swap Python/3.10.4-GCCcore-11.3.0 Python/3.12.3-GCCcore-13.3.0 

The following have been reloaded with a version change:
  1) GCCcore/11.3.0 => GCCcore/13.3.0                                 7) binutils/2.38-GCCcore-11.3.0 => binutils/2.42-GCCcore-13.3.0
  2) OpenSSL/1.1 => OpenSSL/3                                         8) bzip2/1.0.8-GCCcore-11.3.0 => bzip2/1.0.8-GCCcore-13.3.0
  3) Python/3.10.4-GCCcore-11.3.0 => Python/3.12.3-GCCcore-13.3.0     9) libffi/3.4.2-GCCcore-11.3.0 => libffi/3.4.5-GCCcore-13.3.0
  4) SQLite/3.38.3-GCCcore-11.3.0 => SQLite/3.45.3-GCCcore-13.3.0    10) libreadline/8.1.2-GCCcore-11.3.0 => libreadline/8.2-GCCcore-13.3.0
  5) Tcl/8.6.12-GCCcore-11.3.0 => Tcl/8.6.14-GCCcore-13.3.0          11) ncurses/6.3-GCCcore-11.3.0 => ncurses/6.5-GCCcore-13.3.0
  6) XZ/5.2.5-GCCcore-11.3.0 => XZ/5.4.5-GCCcore-13.3.0              12) zlib/1.2.12-GCCcore-11.3.0 => zlib/1.3.1-GCCcore-13.3.0
Note: The module system takes care of any relevant dependencies to the requested module we are trying to load. Therefore, switching from one version to another, the correct version of each dependency is reloaded automatically.

Reset Loaded Modules

To start from a clean environemnt we can use the purge command.
module purge
This will unload all the modules:
[marconstantinou@front02 ~]$ module list

Currently Loaded Modules:
  1) GMP/6.2.1-GCCcore-11.3.0       5) bzip2/1.0.8-GCCcore-13.3.0       9) SQLite/3.45.3-GCCcore-13.3.0  13) Python/3.12.3-GCCcore-13.3.0
  2) GCCcore/13.3.0                 6) ncurses/6.5-GCCcore-13.3.0      10) XZ/5.4.5-GCCcore-13.3.0
  3) zlib/1.3.1-GCCcore-13.3.0      7) libreadline/8.2-GCCcore-13.3.0  11) libffi/3.4.5-GCCcore-13.3.0
  4) binutils/2.42-GCCcore-13.3.0   8) Tcl/8.6.14-GCCcore-13.3.0       12) OpenSSL/3

[marconstantinou@front02 ~]$ module purge
[marconstantinou@front02 ~]$ module list
No modules loaded
Note: It is recommended to use before loading any modules, because modules loaded on your login environment are curried over to your job environment. This is a good way to make sure that there are no left over modules.

3.6. Using conda to Manage Python Virtual Environments

conda is an open-source package management and environment management system widely used in data science, machine learning, and software development. It simplifies the installation, updating, and management of software packages and their dependencies across various programming languages, including Python, R, and C++. conda also enables users to create isolated environments, allowing them to work on multiple projects with different dependencies without conflicts. It supports a wide range of operating systems and can manage libraries for scientific computing, data analysis, and machine learning efficiently.
ℹ️ The official documentation for Anaconda can be found here.

3.6.1. Creating an Environment

You can create an empty environment by running:
# Replace <ENV_NAME> with a name for your environment
[marconstantinou@front02 ~]$ conda create -n <ENV_NAME>
or if you want to create an environment with Python and other packages, run this:
# Replace <ENV_NAME> with a name for your environment
# Replace <PACKAGE> with your desired package
# Replace <VERSION> with your desired version of Python
[marconstantinou@front02 ~]$ conda create -n <ENV_NAME> python=<VERSION> <PACKAGE>=<VERSION>
Example: Creating an environment with Python 3.11 and other specific libraries
conda create -n myenv python=3.11 beautifulsoup4 docutils jinja2=3.1.4 wheel

3.6.2. Activating an Environment

To activate your environment, simply run:
# Replace <ENV_NAME> with the name of the environment you want to activate
[marconstantinou@front02 ~]$ conda activate <ENV_NAME>
(ENV_NAME)[marconstantinou@front02 ~]$ 
You should now be able to see (ENV_NAME) next to your user name.

3.6.3. Switching Between Environments

If you want to switch to a different environment you can run these commands:
# Show all available environments
(base)[marconstantinou@front02 ~]$ conda info --envs
# conda environments:
#
base                  *  /nvme/h/buildsets/eb_cyclone_rl/software/Anaconda3/2023.03-1
juplab                   /nvme/h/marconstantinou/.conda/envs/juplab
myenv                    /nvme/h/marconstantinou/.conda/envs/myenv

# Replace <ENV_NAME> with the name of the environment you want to switch to
(base)[marconstantinou@front02 ~]$ conda activate <ENV_NAME>
(ENV_NAME)[marconstantinou@front02 ~]$ 
ℹ️ Activating a different environment will deactivate your current one.

3.6.4. Deactivating an environment

To deactivate your current environment, simply type:
(ENV_NAME)[marconstantinou@front02 ~]$ conda deactivate
(base)[marconstantinou@front02 ~]$ 
💡 Upon deactivation, the environment will switch to the base acting as the default environment. If you want to deactivate conda completely, repeat conda deactivate.

3.6.5. Exporting an Environment

Do not attempt to copy the environment's files to a different machine. It will not recreate the environment. We must export the environment and install it again. To export the environment, simply run:
# Replace <ENV_NAME> with the name of the environment you want exported
(base)[marconstantinou@front02 ~]$ conda activate <ENV_NAME>
(ENV_NAME)[marconstantinou@front02 ~]$ conda env export > environment.yml
ℹ️ This will handle both conda and pip's packages.
In your current directory you should see a file called environment.yml. You can take this file to the machine you want to export the environment and run:
(base)[marconstantinou@front02 ~]$ conda env create -f environment.yml
After this, you can activate the environment and use it as is.

3.7. Using venv to Manage Python Virtual Environments

The venv module in Python is a tool to create isolated environments for your projects. This ensures that dependencies for one project don’t interfere with those of another. Here's how to get started with venv.
venv and conda both create isolated environments for Python projects, but they differ in scope and functionality. venv is a lightweight, Python-specific tool for isolating packages installed via pip, relying on the system's Python interpreter. In contrast, conda is a cross-language package and environment manager that can handle both Python and non-Python dependencies, including system libraries, and comes with its own Python interpreter. While venv is simple and built into Python, conda is more feature-rich, making it ideal for data science and projects with complex dependencies.

3.7.1. Creating a Virtual Environment

Navigate to your project's directory:
[marconstantinou@front02 ~]$ cd /path/to/your/project
Create a venv environment:
# REPLACE venv_name with the name you want to give to your environment
[marconstantinou@front02 ~]$ python -m venv venv_name

3.7.2. Activating a Virtual Environment

To start using the virtual environment, you need to activate it via:
[marconstantinou@front02 ~]$ source venv_name/bin/activate
(venv_name)[marconstantinou@front02 ~]$ 

3.7.3. Installing Packages

Once you activate the environment you can start installing packages via simply running:
pip install package_name
Example: Installing numpy
[marconstantinou@front02 ~]$ pip install numpy
(venv_name) [marconstantinou@front02 ~]$ pip install numpy
Collecting numpy
  Downloading numpy-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (62 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.0/62.0 kB 1.2 MB/s eta 0:00:00
Downloading numpy-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.1/16.1 MB 22.2 MB/s eta 0:00:00
Installing collected packages: numpy
Successfully installed numpy-2.2.2
You can see what packages you have installed by typing:
(venv_name) [marconstantinou@front02 ~]$ pip list
Package Version
------- -------
numpy   2.2.2
pip     24.0

3.7.4. Deleting a Virtual Environment

To delete the environment simply type:
(venv_name) [marconstantinou@front02 ~]$ rm -rf venv_name

3.8. Hands-on Exercise

In this exercise, we will:
  1. connect to Cyclone using VS Code (you can use whatever interface you prefer)
  2. create a directory for our small project
  3. load some modules
  4. create a virtual environment for our python scripts
  5. and finally we will run a small python file.

3.8.1. Setup our Project's Directory

Open up VS Code and connect to Cyclone. Once connected, go to the terminal and into your $HOME dir.
⚠️ Please keep in mind that you can do all these by using the graphical interface of VS Code - if you prefer that way, then go ahead and do that.
[marconstantinou@front02 ~]$ pwd
/nvme/h/marconstantinou
If you are not in your $HOME directory, type:
[marconstantinou@front02 ~]$ cd $HOME
To create our hands-on directory, type:
[marconstantinou@front02 ~]$ mkdir tutorial_03_project/
If you followed all the steps until now, you should see a tutorial_03_project directory when you type this command:
[marconstantinou@front02 ~]$ ls -l
total 2
lrwxrwxrwx  1 marconstantinou p232        15 Nov  4 10:20 data_p232 -> /onyx/data/p232
lrwxrwxrwx  1 marconstantinou p232        19 Nov  4 11:22 edu24 -> /onyx/data/edu24
lrwxrwxrwx  1 marconstantinou p232        29 Nov  4 10:20 scratch -> /nvme/scratch/marconstantinou
drwxr-xr-x  2 marconstantinou p232         0 Dec 10 15:26 tutorial_03_project
Go inside that directory:
[marconstantinou@front02 ~]$ cd tutorial_03_project/
Then create a main.py file:
[marconstantinou@front02 ~]$ touch main.py
[marconstantinou@front02 ~]$ ls -l
-rw-r--r-- 1 marconstantinou p232 0 Dec 19 11:40 main.py

alt text

Now that we have our directory and script ready, lets load some module and install some packages.

3.8.2. Load CUDA Module

Again, in your terminal connected to Cyclone, type:
[marconstantinou@front02 ~]$ module avail CUDA

------------------------------------------- /eb/modules/all --------------------------------------------
   CUDA/10.1.243
   CUDA/11.4.1
   CUDA/11.7.0
   CUDA/11.8.0
   CUDA/12.0.0
   CUDA/12.1.0
   CUDA/12.1.1
   CUDA/12.6.0                                                   (D)
   ...

  Where:
   D:  Default Module

If the avail list is too long consider trying:

"module --default avail" or "ml -d av" to just list the default modules.
"module overview" or "ml ov" to display the number of modules for each name.

Use "module spider" to find all possible modules and extensions.
Use "module keyword key1 key2 ..." to search for all possible modules matching any of the "keys".
Let's load CUDA/12.1.1:
[marconstantinou@front02 ~]$ module load CUDA/12.1.1

3.8.3. Create a conda Environment for our Project and Install Some Libraries

We are going to create a conda virtual environment, and install PyTorch which is a Deep Learning framework.
First we need to load Anaconda using the module system:
[marconstantinou@front02 ~]$ module load Anaconda3/2023.03-1
Then run:
[marconstantinou@front02 ~]$ conda init
Now restart your terminal. When you open a new terminal and connect to Cyclone, you should be able to create an environment and activate it.
To do this, type:
(base)[marconstantinou@front02 ~]$ conda create --name dummy_proj pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia
⚠️ This will take some time to install, be patient.
After everything is installed, go ahead and request a single GPU for 30 minutes on GPU partition of Cyclone by typing:
# Start a 30 minute interactive session on a GPU node
(base)[marconstantinou@front02 ~]$ srun --partition=gpu --gres=gpu:1 --time=00:30:00 --pty bash
You might see something like this:
srun: job 1037413 queued and waiting for resources
This mean that cyclone is being utilized, and that our job is in queue until resourcers are found. Please give SLURM some time to allocate some resources to our request.
Once the allocation of resources is successful, the front02 hostname shown on the terminal next to your username will be changed to the allocated node. In this case, the allocated node is gpu01 (Note it might differ from yours!). Then we want to activate our environment:
(base)[marconstantinou@gpu01 ~]$ conda activate dummy_proj
You can check which libraries are installed in your conda environment by typing
(dummy_proj)[marconstantinou@gpu01 ~]$ conda list

alt text

3.8.4. Select the Correct Python Interpreter in VS Code

On the top of VS Code, click and type the following:

> Python: Select Interpreter

alt text

Click enter and then select the newly created conda environment:

alt text

3.8.5. Running a Python Script on a GPU Node

Copy and paste the following code snippet inside the main.py file that we created earlier. This file should be inside the directory tutorial_03_project
import sys

import torch


def check_pytorch_installation():
    try:
        # Check if PyTorch is installed
        print(f"PyTorch version: {torch.__version__}")
    except ImportError:
        print("PyTorch is not installed.")
        sys.exit(1)

def check_cuda_support():
    if torch.cuda.is_available():
        print("CUDA is available!")
        print(f"CUDA version: {torch.version.cuda}")
        print(f"Number of GPUs available: {torch.cuda.device_count()}")
        print(f"GPU Name: {torch.cuda.get_device_name(0)}")
    else:
        print("CUDA is not available. Please ensure that your system has a compatible GPU and CUDA setup.")

def main():
    print("Checking PyTorch and CUDA installation...")
    check_pytorch_installation()
    check_cuda_support()
    print("Verification complete.")

if __name__ == "__main__":
    main()
Now save it, and inside your terminal run:
(dummy_proj)[marconstantinou@gpu01 tutorial_03_project]$ python main.py
⚠️ The above command assumes you are in the directory of the main.py file. If you are in a different directory, you will have to edit the above command.
You should see the following:
Checking PyTorch and CUDA installation...
PyTorch version: 2.5.1
CUDA is available!
CUDA version: 12.1
Number of GPUs available: 1
GPU Name: Tesla V100-SXM2-32GB
Verification complete.
And that's all!
You created a directory for your project, loaded some modules, created a conda environment with some libraries, and then you run some python code on a GPU Node.

3.8.6. Closing our Interactive Job Session

Inside your terminal go ahead and type:
(dummy_proj)[marconstantinou@gpu01 ~]$ squeue --me
You should see 1 job with a JOBID, copy that JOBID and type:
# Replace JOBID with the ID of your job that you just copied
(dummy_proj)[marconstantinou@gpu01 ~]$ scancel JOBID

# Example
(dummy_proj)[marconstantinou@gpu01 ~]$ scancel 1037152

alt text