<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.bwhpc.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=M+Carmesin</id>
	<title>bwHPC Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.bwhpc.de/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=M+Carmesin"/>
	<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/e/Special:Contributions/M_Carmesin"/>
	<updated>2026-04-06T20:05:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15837</id>
		<title>Status</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15837"/>
		<updated>2026-03-17T08:38:10Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Current Status */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= bwHPC Cluster and Service Status Page =&lt;br /&gt;
&lt;br /&gt;
== Current Status ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- OK/green --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#B8FFB8; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#8AFF8A; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
Normal operation of all systems.&lt;br /&gt;
|}&lt;br /&gt;
--!&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- warning/yellow --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#FFD28A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FFC05C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
[[bwUniCluster3.0]] Maintenance&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- alert/red --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#FF8A8A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FF5C5C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&amp;lt;strong&amp;gt;14.3.2026: bwUniCluster: Login Not Possible &amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Due to a technical issue, users have been unable to log in to bwUniCluster 3.0 since Saturday.&lt;br /&gt;
&lt;br /&gt;
We are already working to resolve the issue as quickly as possible. At this time, we do not yet have an estimate of when the problem will be resolved.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Old Messages ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;15.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;09.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* 10.10.: ongoing issue&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
* 2025-10-10T16: Some sites report normal operation. Identity providers need to update DFN information, expected within 24h.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15835</id>
		<title>Status</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15835"/>
		<updated>2026-03-17T08:37:11Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Current Status */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= bwHPC Cluster and Service Status Page =&lt;br /&gt;
&lt;br /&gt;
== Current Status ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- OK/green --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#B8FFB8; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#8AFF8A; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
Normal operation of all systems.&lt;br /&gt;
|}&lt;br /&gt;
--!&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- warning/yellow --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#FFD28A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FFC05C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
[[bwUniCluster3.0]] Maintenance&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- alert/red --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#FF8A8A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FF5C5C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&amp;lt;strong&amp;gt;14.3.2026: bwUniCluster: login impossible &amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Due to a technical issue, users have been unable to log in to bwUniCluster 3.0 since Saturday.&lt;br /&gt;
&lt;br /&gt;
We are already working to resolve the issue as quickly as possible. At this time, we do not yet have an estimate of when the problem will be resolved.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Old Messages ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;15.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;09.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* 10.10.: ongoing issue&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
* 2025-10-10T16: Some sites report normal operation. Identity providers need to update DFN information, expected within 24h.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15833</id>
		<title>Status</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Status&amp;diff=15833"/>
		<updated>2026-03-17T08:36:55Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= bwHPC Cluster and Service Status Page =&lt;br /&gt;
&lt;br /&gt;
== Current Status ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- OK/green --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#B8FFB8; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#8AFF8A; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
Normal operation of all systems.&lt;br /&gt;
|}&lt;br /&gt;
--!&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- warning/yellow --&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
{| style=&amp;quot;  background:#FFD28A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FFC05C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
[[bwUniCluster3.0]] Maintenance&lt;br /&gt;
|}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- alert/red --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#FF8A8A; width:100%;&amp;quot; &lt;br /&gt;
| style=&amp;quot;padding:8px; background:#FF5C5C; font-size:120%; font-weight:bold;  text-align:left&amp;quot; | Status&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
&amp;lt;strong&amp;gt;14.3.2026: bwUniCluster: login impossible &amp;lt;/strong&amp;gt;&lt;br /&gt;
Due to a technical issue, users have been unable to log in to bwUniCluster 3.0 since Saturday.&lt;br /&gt;
&lt;br /&gt;
We are already working to resolve the issue as quickly as possible. At this time, we do not yet have an estimate of when the problem will be resolved.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Old Messages ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;15.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;09.10.2025: central application page (ZAS) [https://zas.bwhpc.de/] currently down&amp;lt;/strong&amp;gt;&lt;br /&gt;
* Renewal and application of new projects (Rechenvorhaben/RV) and registration of new RV members not possible.&lt;br /&gt;
* Filling out the bwUniCluster3.0 questionnaire not possible.&lt;br /&gt;
* 10.10.: ongoing issue&lt;br /&gt;
* Login and compute activities are &#039;&#039;&#039;not&#039;&#039;&#039; affected&lt;br /&gt;
* 2025-10-10T16: Some sites report normal operation. Identity providers need to update DFN information, expected within 24h.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15548</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15548"/>
		<updated>2025-12-02T08:35:16Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on JUSTUS2 and bwUniCLuster 3.0 load suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check &amp;lt;code&amp;gt;module avail math/julia&amp;lt;/code&amp;gt; for the provided versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Recommended Packages ==&lt;br /&gt;
&lt;br /&gt;
Depending on your specific problem, you might speedup your calculations by using the drop-in replacements for the LinearAlebra routines from the Intel oneApi MKL:&lt;br /&gt;
* [https://github.com/JuliaLinearAlgebra/MKL.jl MKL.jl]: dense linear algebra&lt;br /&gt;
* [https://github.com/JuliaSparse/MKLSparse.jl MKLSparse.jl]: sparse linear algebra&lt;br /&gt;
&lt;br /&gt;
If you are developing some low-level numerical codes, you could  profit from the package [https://github.com/JuliaSIMD/LoopVectorization.jl LoopVectorization.jl].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS25 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the bwHPC clusters (on bwUniCluster and JUSTUS2 you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/JuliaPDE/SurveyofPDEPackages Survey of PDE packages]&lt;br /&gt;
&lt;br /&gt;
* [https://book.sciml.ai/ Parallel Computing and Scientific Machine Learning (SciML): Methods and Applications ]&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/Parallel_Programming&amp;diff=15545</id>
		<title>JUSTUS2/Software/Julia/Parallel Programming</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/Parallel_Programming&amp;diff=15545"/>
		<updated>2025-12-02T08:21:51Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Parallel Programming in Julia =&lt;br /&gt;
&lt;br /&gt;
Julia supports several paradigms of parallel programming:&lt;br /&gt;
&lt;br /&gt;
# Implicit multi-threading by math libraries (OpenBLAS, MKL)&lt;br /&gt;
# Explicit multi-threading using Julia threads (e.g. `Threads.@threads for`) or [https://github.com/JuliaSIMD/Polyester.jl Polyester.jl ]&lt;br /&gt;
# Multiple processes on one ore more nodes&lt;br /&gt;
#* &amp;lt;code&amp;gt;Distributed.jl&amp;lt;/code&amp;gt; package and &amp;lt;code&amp;gt;SlurmManager&amp;lt;/code&amp;gt; from [https://github.com/JuliaParallel/SlurmClusterManager.jl &amp;lt;code&amp;gt;SlurmClusterManager.jl&amp;lt;/code&amp;gt;] package, (e.g.&amp;lt;code&amp;gt;@distributed for&amp;lt;/code&amp;gt;-loops)&lt;br /&gt;
#* [https://github.com/JuliaParallel/MPI.jl &amp;lt;code&amp;gt;MPI.jl&amp;lt;/code&amp;gt;]&lt;br /&gt;
# Execution on GPUs/CUDA using [https://cuda.juliagpu.org/stable/ &amp;lt;code&amp;gt;CUDA.jl&amp;lt;/code&amp;gt; ]&lt;br /&gt;
&lt;br /&gt;
All paradigms may be used at the same time, but must be chosen carefully, to obtain the desired performance.&lt;br /&gt;
&lt;br /&gt;
== Implict Multi-Threading ==&lt;br /&gt;
&lt;br /&gt;
The number of threads used by the mathematical linear algebra libraries may be configured using &amp;lt;code&amp;gt;BLAS.set_num_threads()&amp;lt;/code&amp;gt; from the &amp;lt;code&amp;gt;LinearAlgebra&amp;lt;/code&amp;gt; package. Alternatively you can set the environment variables &amp;lt;code&amp;gt;OPENBLAS_NUM_THREADS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;MKL_NUM_THREADS&amp;lt;/code&amp;gt; if you use MKL.&lt;br /&gt;
&lt;br /&gt;
If your code is already multi-threaded, you probably want to set the number of BLAS threads to 1, in order to avoid running too many competing threads, as every Julia thread comes with its own BLAS threads.&lt;br /&gt;
&lt;br /&gt;
== Explicit Multi-Threading ==&lt;br /&gt;
Start Julia with option &amp;lt;code&amp;gt;-t x&amp;lt;/code&amp;gt; where x is &lt;br /&gt;
the number of (Julia) threads or the keyword &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;, which however doesn&#039;t  determine correctly the number of threads requested from SLURM with the option &amp;lt;code&amp;gt;--cpus-per-task&amp;lt;/code&amp;gt;. Alternatively, you can set the environment variable &amp;lt;code&amp;gt;JULIA_NUM_THREADS&amp;lt;/code&amp;gt;. See the [https://docs.julialang.org/en/v1/manual/multi-threading/ Julia documentation] for more details.&lt;br /&gt;
&lt;br /&gt;
== Multiple Processes ==&lt;br /&gt;
With the [https://docs.julialang.org/en/v1/manual/distributed-computing/ Distributed package] Julia has native support for distributed computing using multiple processes on different nodes. To integrate well into SLURM, the use of the [https://github.com/JuliaParallel/ClusterManagers.jl &amp;lt;code&amp;gt;ClusterManagers.jl&amp;lt;/code&amp;gt;], providing the &amp;lt;code&amp;gt;addprocs_slurm()&amp;lt;/code&amp;gt; function, is advised to spawn the worker processes. &lt;br /&gt;
&lt;br /&gt;
== MPI ==&lt;br /&gt;
&lt;br /&gt;
Distributed computing using MPI can be performed leveraging the [https://github.com/JuliaParallel/MPI.jl &amp;lt;code&amp;gt;MPI.jl&amp;lt;/code&amp;gt;] package, which provides Julia wrappers for most of the standard MPI functions.&lt;br /&gt;
&lt;br /&gt;
== CUDA ==&lt;br /&gt;
Julia supports computations on NVidia GPUS using the [https://cuda.juliagpu.org/stable/ CUDA.jl] package. It provides the possibility to write own kernels as well as wrappers for libraries like cuBLAS or cuFFT, that contain implementations of standard numerical routines optimized for GPUs.&lt;br /&gt;
&lt;br /&gt;
== Higher Level Packages ==&lt;br /&gt;
&lt;br /&gt;
There are several Julia packages that allow for mixing/changing the different paradigms for parallel computing with minimal code changes:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/JuliaFolds2/FLoops.jl &amp;lt;code&amp;gt;FLoops.jl&amp;lt;/code&amp;gt;] and its backend [https://juliafolds2.github.io/Folds.jl/dev/ &amp;lt;code&amp;gt;Folds.jl&amp;lt;/code&amp;gt;] &lt;br /&gt;
* [https://juliaparallel.org/Dagger.jl/stable/ Dagger.jl] (still quite experimental)&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15544</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15544"/>
		<updated>2025-12-02T08:18:53Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on JUSTUS2 and bwUniCLuster 3.0 load suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check &amp;lt;code&amp;gt;module avail math/julia&amp;lt;/code&amp;gt; for the provided versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS25 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the bwHPC clusters (on bwUniCluster and JUSTUS2 you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/JuliaPDE/SurveyofPDEPackages Survey of PDE packages]&lt;br /&gt;
&lt;br /&gt;
* [https://book.sciml.ai/ Parallel Computing and Scientific Machine Learning (SciML): Methods and Applications ]&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15543</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15543"/>
		<updated>2025-12-02T08:14:59Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check &amp;lt;code&amp;gt;module avail math/julia&amp;lt;/code&amp;gt; for the provided versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS25 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the bwHPC clusters (on bwUniCluster and JUSTUS2 you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/JuliaPDE/SurveyofPDEPackages Survey of PDE packages]&lt;br /&gt;
&lt;br /&gt;
* [https://book.sciml.ai/ Parallel Computing and Scientific Machine Learning (SciML): Methods and Applications ]&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15542</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=15542"/>
		<updated>2025-12-02T07:59:12Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Further documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check &amp;lt;code&amp;gt;module avail math/julia&amp;lt;/code&amp;gt; for the provided versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS25 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the bwHPC clusters (on bwUniCluster and JUSTUS2 you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=15383</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=15383"/>
		<updated>2025-11-06T07:41:00Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Monitoring a Started Job */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File Access ==&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read temporary files from the [[JUSTUS2/Hardware#Storage_Architecture|global file systems]] (HOME and WORK) such as a calculation swap files. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch on disk (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose.&lt;br /&gt;
&lt;br /&gt;
Often, you must configure the the program you are using to write temporary files not to use the global file systems.&lt;br /&gt;
If the program uses the current directory to look for files, you must copy these files to a temporary directory, start the program there and copy/save the results of the calculation in the end.  The contents of /tmp and /scratch are deleted by the automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
Each node has a file system in memory (“ram disk”), that can have a maximum of half the size of the total RAM. Note that files created plus the memory requirements of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with scratch disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just create a tar archive of the whole hole directory (in HOME) instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique.&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Always test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are running more than 1-10 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;| Do not run squeue and other slurm commands in loops or &amp;quot;watch&amp;quot; as not to saturate up the slurm daemon with rpc requests&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport (only on the login nodes), that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
creates an HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -ge 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 48 ]; do&lt;br /&gt;
    sleep 5 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software&amp;diff=15063</id>
		<title>JUSTUS2/Software</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software&amp;diff=15063"/>
		<updated>2025-07-10T08:53:06Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Available Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Environment Modules ==&lt;br /&gt;
Most software is provided as Modules.&lt;br /&gt;
&lt;br /&gt;
Required reading to use: [[Environment Modules]]&lt;br /&gt;
&lt;br /&gt;
== Available Software ==&lt;br /&gt;
&lt;br /&gt;
* Web: Visit [https://www.bwhpc.de/software.php https://www.bwhpc.de/software.php], select &amp;lt;code&amp;gt;Cluster → bwForCluster JUSTUS2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* On the cluster: &amp;lt;code&amp;gt;module avail&amp;lt;/code&amp;gt;[[Environment_Modules#module_help|(→module avail)]]&lt;br /&gt;
&lt;br /&gt;
* Software in Containers: Instructions for loading software in containers: [[JUSTUS2/Software/Singularity|Singularity]]&lt;br /&gt;
* Instructions for using [[JUSTUS2/Software/Python|Python]] on JUSTUS2&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
=== Main Documentation on The Cluster ===&lt;br /&gt;
Documentation for environment modules available on the cluster (shown for a chemistry software called &amp;quot;softname&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
* with command &amp;lt;code&amp;gt;module help chem/softname&amp;lt;/code&amp;gt; [[Environment_Modules#module_help|(→module help)]]&lt;br /&gt;
* examples in &amp;lt;code&amp;gt;$SOFTNAME_EXA_DIR&amp;lt;/code&amp;gt; [[Environment_Modules#Software_job_examples|(→job examples)]]&lt;br /&gt;
&lt;br /&gt;
=== Sometimes Additional Documentation in the Wiki ===&lt;br /&gt;
For some environment modules additional documentation is provided here.&lt;br /&gt;
&amp;lt;!-- this list could be generated via {{Special:PrefixIndex/JUSTUS2/Software/|stripprefix=yes}} &lt;br /&gt;
but then these Pages become orphaned if there is no other link to them&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [[JUSTUS2/Software/ADF|ADF]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Dalton|Dalton]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Gaussian|Gaussian]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Gaussview|Gaussview]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Molden|Molden]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/NAMD|NAMD]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Orca|Orca]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Quantum ESPRESSO|Quantum ESPRESSO]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/SIESTA|SIESTA]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Schrodinger|Schrodinger]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Turbomole|Turbomole]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/VASP|VASP]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia|Julia]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software&amp;diff=15062</id>
		<title>JUSTUS2/Software</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software&amp;diff=15062"/>
		<updated>2025-07-10T08:52:48Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Environment Modules ==&lt;br /&gt;
Most software is provided as Modules.&lt;br /&gt;
&lt;br /&gt;
Required reading to use: [[Environment Modules]]&lt;br /&gt;
&lt;br /&gt;
== Available Software ==&lt;br /&gt;
&lt;br /&gt;
* Web: Visit [https://www.bwhpc.de/software.php https://www.bwhpc.de/software.php], select &amp;lt;code&amp;gt;Cluster → bwForCluster JUSTUS2&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* On the cluster: &amp;lt;code&amp;gt;module avail&amp;lt;/code&amp;gt;[[Environment_Modules#module_help|(→module avail)]]&lt;br /&gt;
&lt;br /&gt;
* Software in Containers: Instructions for loading software in containers: [[JUSTUS2/Software/Singularity|Singularity]]&lt;br /&gt;
* Instructions for using [[JUSTUS2/Software/Python]] on JUSTUS2&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
=== Main Documentation on The Cluster ===&lt;br /&gt;
Documentation for environment modules available on the cluster (shown for a chemistry software called &amp;quot;softname&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
* with command &amp;lt;code&amp;gt;module help chem/softname&amp;lt;/code&amp;gt; [[Environment_Modules#module_help|(→module help)]]&lt;br /&gt;
* examples in &amp;lt;code&amp;gt;$SOFTNAME_EXA_DIR&amp;lt;/code&amp;gt; [[Environment_Modules#Software_job_examples|(→job examples)]]&lt;br /&gt;
&lt;br /&gt;
=== Sometimes Additional Documentation in the Wiki ===&lt;br /&gt;
For some environment modules additional documentation is provided here.&lt;br /&gt;
&amp;lt;!-- this list could be generated via {{Special:PrefixIndex/JUSTUS2/Software/|stripprefix=yes}} &lt;br /&gt;
but then these Pages become orphaned if there is no other link to them&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [[JUSTUS2/Software/ADF|ADF]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Dalton|Dalton]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Gaussian|Gaussian]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Gaussview|Gaussview]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Molden|Molden]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/NAMD|NAMD]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Orca|Orca]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Quantum ESPRESSO|Quantum ESPRESSO]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/SIESTA|SIESTA]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Schrodinger|Schrodinger]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Turbomole|Turbomole]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/VASP|VASP]]&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia|Julia]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15061</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15061"/>
		<updated>2025-07-10T08:45:52Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Recommendations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see [[#Conda|below]])&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your Python environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C/C++ or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking to the Intel MKL. How to pass the compilation/linking options depends on the package. Hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary some_package some_package==VERSION BUILD_OPTIONS&lt;br /&gt;
&lt;br /&gt;
=Conda=&lt;br /&gt;
&lt;br /&gt;
There are several reasons for not using [[Conda]] on the cluster:&lt;br /&gt;
&lt;br /&gt;
* legal: unclear license situation for research with the official Anaconda channel&lt;br /&gt;
* free conda-forge channel provides mostly unoptimized packages &lt;br /&gt;
* conflicting libraries: Conda installs own versions of low-level libraries such as OpenMPI, that do not work well together with Slurm.&lt;br /&gt;
&lt;br /&gt;
However, there might be some valid use cases:&lt;br /&gt;
&lt;br /&gt;
* some packages are only available via conda&lt;br /&gt;
* simple installation for testing some software before doing an optimized build&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15060</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15060"/>
		<updated>2025-07-10T08:44:58Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Recommendations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see [[#Conda|below]])&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C/C++ or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking to the Intel MKL. How to pass the compilation/linking options depends on the package. Hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary some_package some_package==VERSION BUILD_OPTIONS&lt;br /&gt;
&lt;br /&gt;
=Conda=&lt;br /&gt;
&lt;br /&gt;
There are several reasons for not using [[Conda]] on the cluster:&lt;br /&gt;
&lt;br /&gt;
* legal: unclear license situation for research with the official Anaconda channel&lt;br /&gt;
* free conda-forge channel provides mostly unoptimized packages &lt;br /&gt;
* conflicting libraries: Conda installs own versions of low-level libraries such as OpenMPI, that do not work well together with Slurm.&lt;br /&gt;
&lt;br /&gt;
However, there might be some valid use cases:&lt;br /&gt;
&lt;br /&gt;
* some packages are only available via conda&lt;br /&gt;
* simple installation for testing some software before doing an optimized build&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15059</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15059"/>
		<updated>2025-07-10T08:44:22Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Advanced Users: Building your own optimized libraries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C/C++ or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking to the Intel MKL. How to pass the compilation/linking options depends on the package. Hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary some_package some_package==VERSION BUILD_OPTIONS&lt;br /&gt;
&lt;br /&gt;
=Conda=&lt;br /&gt;
&lt;br /&gt;
There are several reasons for not using [[Conda]] on the cluster:&lt;br /&gt;
&lt;br /&gt;
* legal: unclear license situation for research with the official Anaconda channel&lt;br /&gt;
* free conda-forge channel provides mostly unoptimized packages &lt;br /&gt;
* conflicting libraries: Conda installs own versions of low-level libraries such as OpenMPI, that do not work well together with Slurm.&lt;br /&gt;
&lt;br /&gt;
However, there might be some valid use cases:&lt;br /&gt;
&lt;br /&gt;
* some packages are only available via conda&lt;br /&gt;
* simple installation for testing some software before doing an optimized build&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15058</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15058"/>
		<updated>2025-07-10T08:43:08Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Advanced Users: Building your own optimized libraries */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C/C++ or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking the to MKL. How to pass the compilation/lionking options depends on the package. hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary my_package my_package==VERSION BUILD_OPTIONS&lt;br /&gt;
&lt;br /&gt;
=Conda=&lt;br /&gt;
&lt;br /&gt;
There are several reasons for not using [[Conda]] on the cluster:&lt;br /&gt;
&lt;br /&gt;
* legal: unclear license situation for research with the official Anaconda channel&lt;br /&gt;
* free conda-forge channel provides mostly unoptimized packages &lt;br /&gt;
* conflicting libraries: Conda installs own versions of low-level libraries such as OpenMPI, that do not work well together with Slurm.&lt;br /&gt;
&lt;br /&gt;
However, there might be some valid use cases:&lt;br /&gt;
&lt;br /&gt;
* some packages are only available via conda&lt;br /&gt;
* simple installation for testing some software before doing an optimized build&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15054</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15054"/>
		<updated>2025-07-09T08:52:50Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking the to MKL. How to pass the compilation/lionking options depends on the package. hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary my_package my_package==VERSION BUILD_OPTIONS&lt;br /&gt;
&lt;br /&gt;
=Conda=&lt;br /&gt;
&lt;br /&gt;
There are several reasons for not using [[Conda]] on the cluster:&lt;br /&gt;
&lt;br /&gt;
* legal: unclear license situation for research with the official Anaconda channel&lt;br /&gt;
* free conda-forge channel provides mostly unoptimized packages &lt;br /&gt;
* conflicting libraries: Conda installs own versions of low-level libraries such as OpenMPI, that do not work well together with Slurm.&lt;br /&gt;
&lt;br /&gt;
However, there might be some valid use cases:&lt;br /&gt;
&lt;br /&gt;
* some packages are only available via conda&lt;br /&gt;
* simple installation for testing some software before doing an optimized build&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15053</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15053"/>
		<updated>2025-07-09T08:26:47Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Recommendations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking the to MKL. How to pass the compilation/lionking options depends on the package. hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary my_package my_package==VERSION BUILD_OPTIONS&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15052</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15052"/>
		<updated>2025-07-09T08:24:11Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
* &amp;lt;b&amp;gt;Do never ever activate a python environment, neither venv nor conda, in your .bashrc! This may break various things.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as [[Environment Modules|environment modules]]&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Always load the environment modules before activating your environments! &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_scipy&lt;br /&gt;
&lt;br /&gt;
or if you don&#039;t need SciPy&lt;br /&gt;
&lt;br /&gt;
 module avail numlib/python_numpy&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other Python versions!&lt;br /&gt;
&lt;br /&gt;
==Advanced Users: Building your own optimized libraries==&lt;br /&gt;
If you need more Python packages that depend on C or Fortran code for numerical calculations, we recommend building them manually with optimizations and linking the to MKL. How to pass the compilation/lionking options depends on the package. hence see its documentation. There is usually a section like “Building From Source“&lt;br /&gt;
&lt;br /&gt;
A typical workflow might be&lt;br /&gt;
&lt;br /&gt;
 module load numlib/mkl/2024.2.1&lt;br /&gt;
 module load compiler/gnu/14.2&lt;br /&gt;
 export CFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export FFLAGS=&amp;quot;-O2 -march=native&amp;quot;&lt;br /&gt;
 export CXXFLAGS=&amp;quot;-02 -march=native&amp;quot; &lt;br /&gt;
 pip install --no-binary my_package my_package==VERSION BUILD_OPTIONS&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15051</id>
		<title>JUSTUS2/Software/Python</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Python&amp;diff=15051"/>
		<updated>2025-07-09T07:49:17Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: Created page with &amp;quot;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see Development/Python.  =Recommendations=  * Don&amp;#039;t use conda (see below) * Don&amp;#039;t use the system python for computation intensive work  * Use optimized numerical libraries (SciPy, NumPy) provided as environment modules * Use virtual environments (venv) * Use pip for in...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page covers information on Python specific to JUSTUS2. For general information valid on all clusters see [[Development/Python]].&lt;br /&gt;
&lt;br /&gt;
=Recommendations=&lt;br /&gt;
&lt;br /&gt;
* Don&#039;t use conda (see below)&lt;br /&gt;
* Don&#039;t use the system python for computation intensive work&lt;br /&gt;
&lt;br /&gt;
* Use optimized numerical libraries (SciPy, NumPy) provided as environment modules&lt;br /&gt;
* Use [[Development/Python#Virtual Environments (venv)|virtual environments (venv)]]&lt;br /&gt;
* Use [[Development/Python#Package Manager (pip)|pip]] for installing further packages&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Optimized Libraries=&lt;br /&gt;
&lt;br /&gt;
We provide versions of SciPy and NumPy, that are optimized for the JUSTUS2 CPUs and make use of the highly optimized linear algebra routines provided by [[Development/MKL| Intel MKL]].&lt;br /&gt;
&lt;br /&gt;
For available versions see&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;module avail numlib/python_scipy&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that each SciPy module also loads the corresponding NumPy and Python modules. Please don&#039;t try to mix with other python versions!&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14982</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14982"/>
		<updated>2025-06-23T13:22:50Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* File Access */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File Access ==&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read temporary files from the [[JUSTUS2/Hardware#Storage_Architecture|global file systems]] (HOME and WORK) such as a calculation swap files. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch on disk (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose.&lt;br /&gt;
&lt;br /&gt;
Often, you must configure the the program you are using to write temporary files not to use the global file systems.&lt;br /&gt;
If the program uses the current directory to look for files, you must copy these files to a temporary directory, start the program there and copy/save the results of the calculation in the end.  The contents of /tmp and /scratch are deleted by the automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
Each node has a file system in memory (“ram disk”), that can have a maximum of half the size of the total RAM. Note that files created plus the memory requirements of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with scratch disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just create a tar archive of the whole hole directory (in HOME) instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique.&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Always test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are running more than 1-10 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;| Do not run squeue and other slurm commands in loops or &amp;quot;watch&amp;quot; as not to saturate up the slurm daemon with rpc requests&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport, that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
creates an HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14981</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14981"/>
		<updated>2025-06-23T13:13:33Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Submitting Jobs on the bwForCluster JUSTUS 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File Access ==&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read temporary files from the [[JUSTUS2/Hardware#Storage_Architecture|global file systems]] (HOME and WORK) such as a calculation swap files. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch on disk (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose.&lt;br /&gt;
&lt;br /&gt;
Often, you must configure the the program you are using to write temporary files not to use the global file systems.&lt;br /&gt;
If the program uses the current directory to look for files, you must copy these files to a temporary directory, start the program there and copy/save the results of the calculation in the end.  The contents of the of /tmp and /scratch are deleted by the automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
Each node has a file system in memory (“ram disk”), that can have a maximum of half the size of the total RAM. Note that files created plus the memory requirements of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with scratch disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just create a tar archive of the whole hole directory (in HOME) instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique. &lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Always test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are running more than 1-10 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;| Do not run squeue and other slurm commands in loops or &amp;quot;watch&amp;quot; as not to saturate up the slurm daemon with rpc requests&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport, that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
creates an HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14980</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14980"/>
		<updated>2025-06-23T13:02:33Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Submitting Jobs on the bwForCluster JUSTUS 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
== File Access ==&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read temporary files from the [[JUSTUS2/Hardware#Storage_Architecture|global file systems]] (HOME and WORK) such as a calculation swap files. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch on disk (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose.&lt;br /&gt;
&lt;br /&gt;
Often, you must configure the the program you are using to write temporary files not to use the global file systems.&lt;br /&gt;
If the program uses the current directory to look for files, you must copy these files to a temporary directory, start the program there and copy/save the results of the calculation in the end.  The contents of the of /tmp and /scratch are deleted by the automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
Each node has a file system in memory (“ram disk”), that can have a maximum of half the size of the total RAM. Note that files created plus the memory requirements of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with scratch disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just create a tar archive of the whole hole directory (in HOME) instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique. &lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Always test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are running more than 1-10 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;| Do not run squeue and other slurm commands in loops or &amp;quot;watch&amp;quot; as not to saturate up the slurm daemon with rpc requests&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport, that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
creates an HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14889</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14889"/>
		<updated>2025-06-04T07:57:25Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Monitoring a Started Job */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems (HOME and WORK) as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just tar the whole directory instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique. &lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are only running more than 1-5 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport, that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
creates an HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14888</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14888"/>
		<updated>2025-06-04T07:56:46Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Monitoring Your Jobs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks or the original slurm documentation.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=06:00:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=00:14:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:  --time=00:14:00 should start your job very quickly. see [[#Testing Your Jobs]]&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems (HOME and WORK) as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
mkdir -p $SCRATCH/mycalculation&lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH/mycalculation&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH/mycalculation&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/mycalculation/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If there are many files or you don&#039;t know exactly how the output files are called, you can just tar the whole directory instead of using cp:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
tar -cvzf $HOME/resultdir/mycalculation-${SLURM_JOB_ID}.tgz&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$SLURM_JOB_ID contains the jobid in slurm during the run on the node and so makes sure the filename is unique. &lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Default Values ===&lt;br /&gt;
Some values will be set by default if you do not specify them for your job. &lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Option || Equivalient To || Meaning&lt;br /&gt;
|-&lt;br /&gt;
|Runtime: || --time=02:00:00 || 2 hours&lt;br /&gt;
|-&lt;br /&gt;
|Nodes:  ||--nodes=1  ||one node&lt;br /&gt;
|-&lt;br /&gt;
|Tasks: || --tasks-per-node=1  ||one task per node&lt;br /&gt;
|-&lt;br /&gt;
|Cores: || --cpus-per-task=1 ||one core per task&lt;br /&gt;
|-&lt;br /&gt;
|Memory: || --mem-per-cpu=2gb  ||2 GB per core&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!|| Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small|| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium|| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large|| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat|| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
&lt;br /&gt;
Test things first with few jobs before you roll out hundreds of jobs!&lt;br /&gt;
&lt;br /&gt;
Please ensure at minimum: &lt;br /&gt;
* are my jobs using the amount of cores I requested&lt;br /&gt;
* is my job using near to the amount of memory I requested&lt;br /&gt;
&lt;br /&gt;
If you are only running more than 1-5 jobs: &lt;br /&gt;
&lt;br /&gt;
* are my jobs running at the very least over 10 minutes&lt;br /&gt;
* do my jobs scale reasonably well &amp;amp;rarr; [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This does not work for already completed jobs. When enabled in slurm, one can see those job scripts with &amp;lt;code&amp;gt;sacct -B -j 6260301&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To get a live overview of the current resource usage on the node, use the command&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;htop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
On the GPU nodes, the usage of the GPU(s) can be visualized using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;nvtop&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Further, we provide the tool jobreport, that generates plots for the resource usage over time of a given job.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
generates HTML file with these plots in the current directory. For convenience, the report may alternatively be sent as email using&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;jobreport -E max.mustermann@uni-ulm.de 6260301 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Efficiency / Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
The more resources you use, the more important efficiency becomes. If you just run 3-5 jobs that take under a day, just go ahead and choose roughly sane defaults. If you submit hundreds or thousands of jobs - jobs that will accumulate years of CPU compute time (by using many CPU cores), then think very carefully about your jobs and take some time to do trial runs until you are sure your calculations are run well. &lt;br /&gt;
&lt;br /&gt;
Also consider these non-technical things:&lt;br /&gt;
* does the calculation give me all the results I need? &lt;br /&gt;
&amp;amp;rarr; rerunning calculations is extremely wasteful&lt;br /&gt;
* am I using the most efficient algorithm? &lt;br /&gt;
&amp;amp;rarr; using better algorithms can reduce the CPU time needed by an order of magnitude or two. And this can sometimes be something as simple as arranging loops in a more clever way or avoiding slow storage. &lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
* using $HOME or work directories for scratch space (expressively forbidden for $HOME, discouraged for work directories, except for multinode jobs that specifically need this for communication)&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
*    not using full node capacity&lt;br /&gt;
*    using more cores than what your computational problem can be split into &amp;amp;rarr; see [[Scaling]]&lt;br /&gt;
&lt;br /&gt;
== User-exclusive Nodes on Justus2 ==&lt;br /&gt;
&lt;br /&gt;
For several reasons, Justus2 nodes are assigned to one user exclusively. That means that you are responsible for using the full compute node efficiently, as no jobs from other users can fill gaps!&lt;br /&gt;
&lt;br /&gt;
Several key points to accomplishing that:&lt;br /&gt;
&lt;br /&gt;
* Use dividers of the core number:&lt;br /&gt;
&lt;br /&gt;
The Justus2 nodes have 48 cores, two sockets with 24 cores each. Use dividers of 48 to be able to use all cores of the node (e.g. 8). Be aware, that when you choose 16, one job will be executed half on one of the CPUs and the other half on the other. This might be suboptimal.&lt;br /&gt;
* Be aware of memory resources: &lt;br /&gt;
&lt;br /&gt;
When you request more memory per core than the &amp;quot;small&amp;quot; nodes on Justus2 have per core, your jobs will not be able to use all cores on the small nodes - or will have to wait for the rarer spaces on the nodes with more memory. Try to estimate your memory requirements well and if you need more than 3.8GB per core, consider mixing in jobs with lower memory requirements to fill the nodes&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development&amp;diff=14870</id>
		<title>Development</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development&amp;diff=14870"/>
		<updated>2025-05-20T08:37:49Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Scripting Languages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Compiling Software ==&lt;br /&gt;
&lt;br /&gt;
Overview of [[Development/General compiler usage|general compiler usage]]&lt;br /&gt;
&lt;br /&gt;
== Parallel Programming ==&lt;br /&gt;
Overview on [[Development/Parallel_Programming | parallel programming with OpenMP and MPI]].&lt;br /&gt;
&lt;br /&gt;
== Environment Modules ==&lt;br /&gt;
Compiler, libraries and development tools are provided as environment modules.&lt;br /&gt;
&lt;br /&gt;
Required reading to use: [[Environment Modules]]&lt;br /&gt;
&lt;br /&gt;
== Available Development Software ==&lt;br /&gt;
Visit [https://www.bwhpc.de/software.php https://www.bwhpc.de/software.php] select your cluster and&lt;br /&gt;
* For compiler select &amp;lt;code&amp;gt;Category → compiler&amp;lt;/code&amp;gt;&lt;br /&gt;
* For MPI select &amp;lt;code&amp;gt;Category → mpi&amp;lt;/code&amp;gt;&lt;br /&gt;
* For libraries select &amp;lt;code&amp;gt;Category → lib&amp;lt;/code&amp;gt;&lt;br /&gt;
* For numerical libraries select &amp;lt;code&amp;gt;Category → numlib&amp;lt;/code&amp;gt;&lt;br /&gt;
* For further development tools select &amp;lt;code&amp;gt;Category → devel&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
On a cluster use: &amp;lt;code&amp;gt;module avail &amp;lt;Category&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
Availabe documentation for environment modules: &lt;br /&gt;
* &amp;lt;code&amp;gt;module help&amp;lt;/code&amp;gt;&lt;br /&gt;
* examples in &amp;lt;code&amp;gt;$SOFTNAME_EXA_DIR&amp;lt;/code&amp;gt;&lt;br /&gt;
* additional docu in this wiki&lt;br /&gt;
&lt;br /&gt;
== Documentation in the Wiki ==&lt;br /&gt;
Environment modules and tools for software development and parallel programming with additional documentation here in the wiki:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Integrated Development Environments ===&lt;br /&gt;
* [[Development/VS_Code|Visual Studio Code]]&lt;br /&gt;
&lt;br /&gt;
=== Compiler and Debugger ===&lt;br /&gt;
* [[Development/GCC|GCC]]&lt;br /&gt;
* [[Development/GDB|GDB]]&lt;br /&gt;
* [[Development/Intel_Compiler|Intel Compiler]]&lt;br /&gt;
&lt;br /&gt;
=== Development Tools ===&lt;br /&gt;
* [[Development/Score-P|Score-P]]:&amp;lt;br /&amp;gt;Tracing of OpenMP-, MPI- and GPU-parallel applications for Vampir and other performance analysis tools.&lt;br /&gt;
* [[Development/Vampir_and_VampirServer|Vampir and VampirServer]]:&amp;lt;br /&amp;gt;Highly scalable Performance Analysis of OpenMP-, MPI- and GPU-parallel applications.&lt;br /&gt;
* [[Development/Pahole|Pahole]]:&amp;lt;br /&amp;gt;Analyse data structures for cache-line alignment and (un)necessary holes that increase data structure size&lt;br /&gt;
* [[Development/Valgrind|Valgrind]]:&amp;lt;br /&amp;gt;Very valuable framework with multiple tools, e.g. to detect memory access errors&lt;br /&gt;
* Forge:&amp;lt;br /&amp;gt;Tools for debugging (arm DDT) and performance analysis (arm MAP)&lt;br /&gt;
&lt;br /&gt;
=== Libraries and Numerical Libraries ===&lt;br /&gt;
* [[Development/GSL|GSL]]&lt;br /&gt;
* [[Development/FFTW|FFTW]]&lt;br /&gt;
* [[Development/MKL|MKL]]&lt;br /&gt;
=== Scripting Languages ===&lt;br /&gt;
* [[Development/Julia|Julia]]&lt;br /&gt;
* [[Development/Python|Python]]&lt;br /&gt;
&lt;br /&gt;
=== Development Environments ===&lt;br /&gt;
* [[Development/Conda|Conda]]&lt;br /&gt;
* [[Development/Containers|Containers]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14831</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14831"/>
		<updated>2025-05-12T10:26:24Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check &amp;lt;code&amp;gt;module avail math/julia&amp;lt;/code&amp;gt; for the provided versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14830</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14830"/>
		<updated>2025-05-12T10:25:49Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Availability */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 and JUSTUS 2, Julia is available as module. Check `module avail math/julia` for the provides versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14829</id>
		<title>Development/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=Development/Julia&amp;diff=14829"/>
		<updated>2025-05-12T10:25:34Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: Created page with &amp;quot;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.  There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.  The Julia module on Justus loads suitable versio...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Availability ==&lt;br /&gt;
&lt;br /&gt;
On UniCluster3.0 ans JUSTUS 2, Julia is available as module. Check `module avail math/julia` for the provides versions. In case there is no suitable version, you can install Julia to your home directory using the [https://julialang.org/install/ JuliaUP] installer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=14828</id>
		<title>JUSTUS2/Software/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=14828"/>
		<updated>2025-05-12T09:54:30Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Softwarepage|math/julia}}&lt;br /&gt;
&lt;br /&gt;
{| width=600px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Description !! Content&lt;br /&gt;
|-&lt;br /&gt;
| module load&lt;br /&gt;
| math/julia&lt;br /&gt;
|-&lt;br /&gt;
| Availability&lt;br /&gt;
| [[bwUniCluster]] &amp;amp;#124; [[JUSTUS2]]&lt;br /&gt;
|-&lt;br /&gt;
| License&lt;br /&gt;
| MIT License&lt;br /&gt;
|-&lt;br /&gt;
|Citing&lt;br /&gt;
| [https://github.com/JuliaLang/julia/blob/master/CITATION.bib]&lt;br /&gt;
|-&lt;br /&gt;
| Links&lt;br /&gt;
| [https://julialang.org/ Project homepage] &amp;amp;#124; [https://docs.julialang.org/en/v1/ Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Graphical Interface&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exist packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.&lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=BwUniCluster3.0/Jupyter&amp;diff=14807</id>
		<title>BwUniCluster3.0/Jupyter</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=BwUniCluster3.0/Jupyter&amp;diff=14807"/>
		<updated>2025-05-07T07:44:51Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Julia language */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Jupyter can be used as an alternative to accessing HPC resources via SSH. For this purpose only a web browser is required. Within the website source code of different programming languages can be edited and executed. Furthermore different user interfaces and terminals are available.&lt;br /&gt;
&lt;br /&gt;
= Short description of Jupyter =&lt;br /&gt;
&lt;br /&gt;
Jupyter is a web application, central component of Jupyter is the &#039;&#039;&#039;Jupyter Notebook&#039;&#039;&#039;. It is a document, which can contain formatted text, executable code sections and (interactive) visualizations (image, sound, video, 3D views).&lt;br /&gt;
&lt;br /&gt;
The Jupyter notebooks are executed in an interactive session on the compute nodes of the respective cluster. Access is via any modern web browser. Data is prepared and visualized on the server and therefore does not have to be transmitted over the network. Only the resulting text, image, sound and video data is transmitted. Starting point of a Jupyter session is the HOME directory of the user on the respective cluster. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;JupyterLab&#039;&#039;&#039; is a modern user interface, within which one or more Jupyter notebooks can be opened, edited and executed. The individual notebooks can be arranged as tabs or tiled. JupyterLab is the standard user interface. Besides JupyterLab the classic notebook user interface is available, in which only one Jupyter notebook per browser tab can be opened at a time.&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;Jupyter Kernel&#039;&#039;&#039; describes a separate process, in which one Jupyter Notebook is executed at a time. Different kernels are available for different programming languages or language versions.&lt;br /&gt;
&lt;br /&gt;
Before a Jupyter session is started, the access authorization must be checked first. This is done via &#039;&#039;&#039;JupyterHub&#039;&#039;&#039;, where the resources are selected, for example the number of CPU cores, GPUs or the required main memory.&lt;br /&gt;
&lt;br /&gt;
A detailed documentation of the Jupyter project can be found at [https://jupyter.readthedocs.io https://jupyter.readthedocs.io].&lt;br /&gt;
&lt;br /&gt;
= Access requirements =&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
[[Image:Attention.svg|center|25px]]&lt;br /&gt;
|style=&amp;quot;padding:5px; background:#cef2e0; text-align:left&amp;quot;|&lt;br /&gt;
Access to Jupyter is &#039;&#039;&#039;limited to IP addresses from the BelWü network&#039;&#039;&#039;.&lt;br /&gt;
All home institutions of our current users are connected to BelWü, so if you are on your campus network (e.g. in your office or on the Campus WiFi) you should be able to connect to bwUniCluster 3.0 without restrictions.&lt;br /&gt;
If you are outside one of the BelWü networks (e.g. at home), a VPN connection to the home institution or a connection to an SSH jump host at the home institution must be established first.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To use Jupyter on the HPC resources of SCC, the access requirements for [https://wiki.bwhpc.de/e/Registration/bwUniCluster bwUniCluster 3.0] apply. A [https://wiki.bwhpc.de/e/Registration/bwUniCluster registration] is required. Please note, You should&#039;ve completed registration and tested your login once using [https://wiki.bwhpc.de/e/Registration/SSH Secure Shell (ssh)].&lt;br /&gt;
&lt;br /&gt;
= Login process =&lt;br /&gt;
&lt;br /&gt;
Login takes place at &lt;br /&gt;
* bwUniCluster 3.0: [https://uc3-jupyter.scc.kit.edu uc3-jupyter.scc.kit.edu]&lt;br /&gt;
* SDIL: [https://sdil-jupyter.scc.kit.edu sdil-jupyter.scc.kit.edu]&lt;br /&gt;
* HoreKa: [https://hk-jupyter.scc.kit.edu hk-jupyter.scc.kit.edu]&lt;br /&gt;
* HAICORE: [https://haicore-jupyter.scc.kit.edu haicore-jupyter.scc.kit.edu]&lt;br /&gt;
&lt;br /&gt;
For login, your username, your password and a 2-factor authentication are required.&lt;br /&gt;
&lt;br /&gt;
You will first find yourself on a landing page that also gives more information about the currently installed software versions.&lt;br /&gt;
By pressing the login button you will be redirected to the JupyterHub page. Click on Enter JupyterHub to start the login process. Select the organization (e.g. KIT) that has granted you access to the HPC system and press Continue. In the Login section that appears, enter your username and password (not the service password). &lt;br /&gt;
After pressing the Login button you will be redirected to the second factor query page. Enter the one-time password (e.g. from KIT Token or Google Authenticator App) and press Validate. Now you are done with the login process and can start selecting your computing resources.&lt;br /&gt;
&lt;br /&gt;
[[File:Jupyter_Anmeldung.gif|700px]]&lt;br /&gt;
&lt;br /&gt;
= Selection of the compute resources =&lt;br /&gt;
&lt;br /&gt;
The Jupyter notebooks are executed in an interactive session on the compute nodes of the HPC clusters. Just like accessing an interactive session with SSH, resource allocation is done by the Workload Manager Slurm. The selection of resources for Jupyter is realized via drop-down menus. Only jobs with a maximum of one node are possible.&lt;br /&gt;
&lt;br /&gt;
Available resources for selection are&lt;br /&gt;
&lt;br /&gt;
* Number of CPU cores&lt;br /&gt;
* Number of GPUs&lt;br /&gt;
* Runtime&lt;br /&gt;
* Partition/Queue&lt;br /&gt;
* Amount of main memory&lt;br /&gt;
&lt;br /&gt;
If Auto-Reservation is selected the automatic Jupyter reservation of the cluster is enabled.&lt;br /&gt;
&lt;br /&gt;
In normal mode, the grayed-out fields contain reasonable presets, depending on the number of required CPU cores or GPUs respectively. The presets can be bypassed in advanced mode, where further options are available. &lt;br /&gt;
&lt;br /&gt;
Advanced Mode can be activated by clicking on the checkbox of the same name. The following additional options then become available:&lt;br /&gt;
&lt;br /&gt;
* Specification of a reservation&lt;br /&gt;
* LSDF mount option&lt;br /&gt;
* BEEOND mount option&lt;br /&gt;
&lt;br /&gt;
After the selection is made, the interactive job is started with the spawn button. As when requesting interactive compute resources with the `salloc` command, waiting times may occur. These are usually the longer the larger the requested resources are.&lt;br /&gt;
Even if the chosen resources are available immediately, the spawning process may take up to one minute.&lt;br /&gt;
&lt;br /&gt;
[[File:Ressources_neu.gif|500px]]&lt;br /&gt;
&lt;br /&gt;
Please note that in advanced mode, resource combinations can be selected that are impossible to be met. In this case, an error message will appear when the job is spawned.&lt;br /&gt;
&lt;br /&gt;
[[File:Jupyter_Falsche_ressourcen.gif|500px]]&lt;br /&gt;
&lt;br /&gt;
The spawning timeout is currently set to 10 minutes. With a normal workload of the HPC facility, this time is usually sufficient to get interactive resources.&lt;br /&gt;
&lt;br /&gt;
== Prioritized access to computing resources on bwUniCluster 3.0 ==&lt;br /&gt;
The use of Jupyter requires the immediate availability of computing resources since the JupyterLab server is started within an interactive Slurm session. To improve the availability of CPUs/GPUs for interactive supercomputing with Jupyter, &#039;&#039;&#039;automatic reservation&#039;&#039;&#039; for CPU (cpu_il) and GPU (gpu_a100_il) resources has been set up on &#039;&#039;&#039;bwUniCluster 3.0&#039;&#039;&#039;. It is active &#039;&#039;&#039;between 8am and 8pm&#039;&#039;&#039; every weekday. The reservation is automatically active if&lt;br /&gt;
&lt;br /&gt;
* no other reservation is set manually&lt;br /&gt;
* Auto-Reservation is enabled&lt;br /&gt;
&lt;br /&gt;
To give you a better overview of the currently available resources, a status indicator has been implemented. It appears when selecting the number of required CPUs/GPUs and shows whether a Jupyter job of the selected size can currently be started or not. Green means the selected CPU/GPU resources are available instantly. Yellow means only a single additional job of the selected size can be started. Red means there are no GPU resources left that could satisfy the selected amount of resources.&lt;br /&gt;
&lt;br /&gt;
If there are no more resources available within the reservation, you can try selecting a different amount of CPUs/GPUs or activate Advanced Mode and select a different partition. Availability can be estimated using sinfo_t_idle, which is available when logging in via SSH.&lt;br /&gt;
&lt;br /&gt;
= JupyterLab =&lt;br /&gt;
&lt;br /&gt;
JupyterLab is the standard user interface. In the following only its essential functions are briefly introduced. A detailed documentation is available at &lt;br /&gt;
[https://jupyterlab.readthedocs.io https://jupyterlab.readthedocs.io].&lt;br /&gt;
&lt;br /&gt;
== Menu bar ==&lt;br /&gt;
&lt;br /&gt;
The menu bar at the upper edge of JupyterLab has higher-level menus that display the actions available in JupyterLab along with their shortcut keys. The default menus are:&lt;br /&gt;
&lt;br /&gt;
* File: Actions related to files and directories&lt;br /&gt;
* Edit: Actions related to editing documents and other activities&lt;br /&gt;
* View: actions that change the appearance of JupyterLab&lt;br /&gt;
* Run: Actions to execute code in various activities like notebooks and code consoles&lt;br /&gt;
* Kernel: Actions to manage kernels that are separate processes for executing code&lt;br /&gt;
* Tabs: a list of open documents and activities in the Dock Panel&lt;br /&gt;
* Settings: general settings and an editor for advanced settings&lt;br /&gt;
* Help: a list of help links to JupyterLab and the kernel&lt;br /&gt;
&lt;br /&gt;
== Left sidebar ==&lt;br /&gt;
&lt;br /&gt;
In the left sidebar there are foldable tabs. The most relevant ones are:&lt;br /&gt;
&lt;br /&gt;
* File browser: Switch to directories and open files with left mouse button, context menu with right mouse button&lt;br /&gt;
* Running kernels: Overview of running kernels&lt;br /&gt;
* Command overview&lt;br /&gt;
* Tab Overview&lt;br /&gt;
* Lmod software selection: Search and load/unload Lmod software modules&lt;br /&gt;
&lt;br /&gt;
== Main working area ==&lt;br /&gt;
The main working area in JupyterLab allows to arrange, resize and divide documents (notebooks, text files, etc.) and other activities (terminals, code consoles, etc.) in tabs. By holding down the left mouse button, the tabs can be grabbed and repositioned.&lt;br /&gt;
&lt;br /&gt;
In a new JupyterLab session the Launcher tab is opened first. It contains buttons for starting new notebooks, code consoles and other functions. When a notebook is open, a new Launcher tab can be started by pressing the plus symbol in the file browser tab of the left sidebar, by calling &#039;&#039;File &amp;gt; New Launcher&#039;&#039; in the upper menu bar or by the key combination &#039;&#039;Ctrl+Shift+L&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Classic Notebook ==&lt;br /&gt;
&lt;br /&gt;
The classic Jupyter Notebook user interface offers only one open Jupyter Notebook or terminal per browser tab. From the JupyterLab user interface the classic display can be reached in the menu bar under &#039;&#039;Help &amp;gt; Launch Classic Notebook&#039;&#039;. Clicking on the JupyterHub logo in the upper left corner will take you back to the JupyterLab interface.&lt;br /&gt;
&lt;br /&gt;
= Log out =&lt;br /&gt;
&lt;br /&gt;
You can log out from a running Jupyter session by calling &#039;&#039;File &amp;gt; Log Out&#039;&#039; in the upper menu bar. &lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;width: 100%; margin:4px 0 0 0; background:none; border-spacing: 0px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width:100%; border:1px solid #BBBBBB; background:#fff5fa; vertical-align:top; color:#000;&amp;quot; |&lt;br /&gt;
{| style=&amp;quot;width:100%; vertical-align:top; border:0px solid #BBBBBB; padding:4px;&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|{{Red}}| Attention&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Please note that your interactive session will continue in the background!  &lt;br /&gt;
&amp;lt;!--For example, this affects your computing time quota on the ForHLR.--&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
As long as the interactive session is running, you can re-enter it at any time. Depending on the duration of your absence, it may be necessary to re-enter your one-time password and possibly KIT password.&lt;br /&gt;
&lt;br /&gt;
If you want to end the interactive session before it has reached its runtime, you can do so via the Hub Control Panel. Under &#039;&#039;File &amp;gt; Hub Control Panel&#039;&#039; in the upper menu bar, it is opened in a new browser tab. By pressing the &#039;&#039;Stop My Server&#039;&#039; button the session will be terminated. You can now log out using the &#039;&#039;Logout&#039;&#039; button in the upper right corner or start a new session directly using the &#039;&#039;Start My Server&#039;&#039; button, for example with a changed resource selection.&lt;br /&gt;
&lt;br /&gt;
[[File:logout_small.gif|750px]]&lt;br /&gt;
&lt;br /&gt;
= Selection of software =&lt;br /&gt;
&lt;br /&gt;
For the selection of the required Lmod software modules the corresponding tab &#039;&#039;Softwares&#039;&#039; is available in the left sidebar. The list of available modules can be narrowed down by entering the search field. The desired module is loaded by pressing the &#039;&#039;Load&#039;&#039; button. In the list with the loaded modules you can remove them with the &#039;&#039;Unload&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;width: 100%; margin:4px 0 0 0; background:none; border-spacing: 0px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width:100%; border:1px solid #BBBBBB; background:#f5fffa; vertical-align:top; color:#000;&amp;quot; |&lt;br /&gt;
{| style=&amp;quot;width:100%; vertical-align:top; border:0px solid #BBBBBB; padding:4px;&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|{{Green}}| Note&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
On already opened Jupyter Notebooks, newly loaded software modules become active only after restarting the kernel (&#039;&#039;Kernel &amp;gt; Restart Kernel&#039;&#039; in the upper menu bar). Terminals must be closed and reopened.&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:software_small.gif|750px]]&lt;br /&gt;
&lt;br /&gt;
== Software Stacks for Jupyter ==&lt;br /&gt;
Currently 3 special Jupyter software stacks are available via Lmod:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;jupyter/minimal&amp;lt;/code&amp;gt;&lt;br /&gt;
*: Minimal installation of JupyterLab&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;jupyter/base&amp;lt;/code&amp;gt; &lt;br /&gt;
*: Basic installation of JupyterLab.&lt;br /&gt;
*: For a complete list of pre-installed packages, please refer to [https://uc2-jupyter.scc.kit.edu/software-modules/#pre-installed-software-packages this site].&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;jupyter/tensorflow&amp;lt;/code&amp;gt; (default at login, will be deprecated with the advent of bwUniCluster 3.0)&lt;br /&gt;
*: Preinstalled software packages for machine learning applications. Includes among others TensorFlow, Keras, Torch, Pandas, Matplotlib, SKLearn.&lt;br /&gt;
*: For a complete list of pre-installed packages and their respective version, please refer to [https://uc2-jupyter.scc.kit.edu/software-modules/#pre-installed-software-packages this site].&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;jupyter/ai&amp;lt;/code&amp;gt; (will be the new default at login für bwUniCluster 3.0, contains all latest and greatest software for AI workflows)&lt;br /&gt;
*: Preinstalled software packages for machine learning applications. Includes among others TensorFlow, Keras, Torch, Torchvision, Lighning, Pandas, Matplotlib, SKLearn.&lt;br /&gt;
*: For a complete list of pre-installed packages and their respective version, please refer to [https://uc2-jupyter.scc.kit.edu/software-modules/#pre-installed-software-packages this site].&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;jupyter/extensions&amp;lt;/code&amp;gt;&lt;br /&gt;
*: Same packages as tensorflow + extensions&lt;br /&gt;
&lt;br /&gt;
These software stacks can be used both when accessing the cluster via JupyterHub, as well as for conventional access via SSH via module load.&lt;br /&gt;
&lt;br /&gt;
A continuously updated list with the installed packages can be found on the corresponding subpage of the respective cluster:&lt;br /&gt;
&lt;br /&gt;
* bwUniCluster 3.0: [https://uc3-jupyter.scc.kit.edu/software-modules uc3-jupyter.scc.kit.edu/software-modules]&lt;br /&gt;
* HoreKa: [https://hk-jupyter.scc.kit.edu/software-modules hk-jupyter.scc.kit.edu/software-modules]&lt;br /&gt;
&lt;br /&gt;
= Installation of further software =&lt;br /&gt;
The software provided by the Lmod modules jupyter/minimal, jupyter/base and jupyter/tensorflow can be easily supplemented by additional Python packages. There are 2 procedures for this.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;User-Installation (not recommended)&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;pip install --user &amp;lt;packageName&amp;gt; &amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The additional packages are installed under $HOME/.local/lib/python3.11/site-packages/ which is part of PYTHONPATH.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Virtual environments (recommended)&amp;lt;br&amp;gt;&lt;br /&gt;
The user can create and use virtual environments (cf. Virtual environments). Packages provided by the jupyter Lmod modules remain visible and usable.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Virtual environments ==&lt;br /&gt;
&lt;br /&gt;
Python virtual environments allow to use different versions of a package and to keep your local site-packages (accessible under &amp;lt;code&amp;gt;$PYTHONPATH&amp;lt;/code&amp;gt;) free from conflicts.&lt;br /&gt;
&lt;br /&gt;
=== Creation of virtual environment ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python -m venv &amp;lt;myEnv&amp;gt;&lt;br /&gt;
source &amp;lt;myEnv&amp;gt;/bin/activate  &lt;br /&gt;
pip install &amp;lt;packageName&amp;gt;  &lt;br /&gt;
deactivate&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The additional packages are installed under &amp;lt;code&amp;gt;&amp;lt;myEnv&amp;gt;/lib/python3.11/site-packages/&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Usage of virtual environment ===&lt;br /&gt;
&lt;br /&gt;
In order to use the virtual environment, it has to be activated via &amp;lt;code&amp;gt;source &amp;lt;myEnv&amp;gt;/bin/activate&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;PYTHONPATH&amp;lt;/code&amp;gt; is set accordingly. Deactivation of the venv is done via &amp;lt;code&amp;gt;deactivate&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Usage of virtual environment in JupyterLab ===&lt;br /&gt;
&lt;br /&gt;
To be able to use the virtual environments within JupyterLab, a corresponding kernel has to be installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
source &amp;lt;myEnv&amp;gt;/bin/activate&lt;br /&gt;
python -m ipykernel install \&lt;br /&gt;
    --user \&lt;br /&gt;
    --name myEnv \&lt;br /&gt;
    --display-name &amp;quot;Python (myEnv)&amp;quot; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the kernel (and possibly refreshing the browser window), a button named &amp;quot;myEnv&amp;quot; is available in JupyterLab. The kernel can also be selected from the drop-down menu.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention&#039;&#039;&#039;&lt;br /&gt;
The (Lmod) base module you used in the Creation of virtual environment step must be loaded to use the venv. However, to be on the safe side, you can also use the system Python (&amp;lt;code&amp;gt;/usr/bin/python3.11&amp;lt;/code&amp;gt;) at creation time, which is available even without any &amp;lt;code&amp;gt;jupyter/{base,tensorflow}&amp;lt;/code&amp;gt; module loaded.&lt;br /&gt;
&lt;br /&gt;
== Examples on Data processing, Machine Learning &amp;amp; Visualization ==&lt;br /&gt;
&lt;br /&gt;
In the [https://github.com/hpcraink/workshop-parallel-jupyter/ workshop repository] the usage and best practices on Python in general, and the packages NumPy, Pandas, SciKit and Dask are provided, containing running examples based on open data. It also explains, how Jupyter interacts with pre-installed and your own provided environments.&lt;br /&gt;
&lt;br /&gt;
== R language ==&lt;br /&gt;
&lt;br /&gt;
In order to use R language in JupyterLab, the Lmod module &amp;lt;code&amp;gt;math/R&amp;lt;/code&amp;gt; has to be loaded (blue button in JupyterLab or &amp;lt;code&amp;gt;module add math/R&amp;lt;/code&amp;gt; in terminal) and a corresponding kernel has to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
R&lt;br /&gt;
install.packages(&#039;IRkernel&#039;)&lt;br /&gt;
IRkernel::installspec()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the kernel , a button named &amp;quot;R&amp;quot; is available in JupyterLab. The kernel can also be selected from the drop-down menu.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention:&#039;&#039;&#039;&lt;br /&gt;
Don&#039;t forget to load the &amp;lt;code&amp;gt;math/R&amp;lt;/code&amp;gt; module (blue button) before using the kernel.&lt;br /&gt;
&lt;br /&gt;
== Julia language ==&lt;br /&gt;
&lt;br /&gt;
In order to use Julia language in JupyterLab, the Lmod module &amp;lt;code&amp;gt;math/julia/1.10.8&amp;lt;/code&amp;gt; has to be loaded (blue button in JupyterLab or &amp;lt;code&amp;gt;module math/julia/1.10.8&amp;lt;/code&amp;gt; in terminal). When the module is loaded from the JupytherLab UI, the corresponding kernel will be installed. If you use the terminal, this has to be done manually&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
julia&lt;br /&gt;
]&lt;br /&gt;
add IJulia&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing the kernel, a button named &amp;quot;Julia 1.10.8&amp;quot; is available in JupyterLab. The kernel can also be selected from the drop-down menu.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention:&#039;&#039;&#039;&lt;br /&gt;
Don&#039;t forget to load the &amp;lt;code&amp;gt;math/julia/1.10.8&amp;lt;/code&amp;gt; module (blue button) before using the kernel.&lt;br /&gt;
&lt;br /&gt;
= Jupyter Container Mode =&lt;br /&gt;
&lt;br /&gt;
The container integration on the jupyterhub is done via pyxis. In order to use it the checkmark for container mode has to be clicked. Available options are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt; --container-image:&amp;lt;/code&amp;gt; The container image to use. Corresponds to the pyxis option --container-image&lt;br /&gt;
* &amp;lt;code&amp;gt; --container-name:&amp;lt;/code&amp;gt; The name of the image to use. Corresponds to the pyxis option --container-name. Already downloaded containers in ~/.local/share/enroot can be startet by simply specifing their name.&lt;br /&gt;
* &amp;lt;code&amp;gt; --container-mount-home:&amp;lt;/code&amp;gt; Corresponds to the pyxis option --container-mount-home. Mounts the home-directory&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention:&#039;&#039;&#039;&lt;br /&gt;
Make sure Python3.11 and pip are installed in the Container or the notebook will not spawn. This can be checked via command python3.11 -m pip list inside your container&lt;br /&gt;
&lt;br /&gt;
It is advised to create the container prior via e.G. enroot and install all necessary software. For more information see [https://wiki.bwhpc.de/e/BwUniCluster2.0/Containers#SLURM_Integration here]&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=User:M_Carmesin/Planning_your_Jobs&amp;diff=14433</id>
		<title>User:M Carmesin/Planning your Jobs</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=User:M_Carmesin/Planning_your_Jobs&amp;diff=14433"/>
		<updated>2025-03-24T14:29:43Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* CPUs&lt;br /&gt;
&lt;br /&gt;
* Memory&lt;br /&gt;
&lt;br /&gt;
* File System&lt;br /&gt;
&lt;br /&gt;
* GPU&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=User:M_Carmesin/Planning_your_Jobs&amp;diff=14432</id>
		<title>User:M Carmesin/Planning your Jobs</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=User:M_Carmesin/Planning_your_Jobs&amp;diff=14432"/>
		<updated>2025-03-24T14:25:11Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: Created page with &amp;quot;==CPUs==  ==Memory==  ==File System==  ==GPU==&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==CPUs==&lt;br /&gt;
&lt;br /&gt;
==Memory==&lt;br /&gt;
&lt;br /&gt;
==File System==&lt;br /&gt;
&lt;br /&gt;
==GPU==&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14431</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14431"/>
		<updated>2025-03-24T14:21:57Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Submitting Jobs on the bwForCluster JUSTUS 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems (HOME and WORK) as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14335</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14335"/>
		<updated>2025-03-12T12:09:37Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Many One-Core Jobs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One or Few-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
Jobs that use only a few CPU cores can lead to very inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, the starting and finishing of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many few-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14334</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14334"/>
		<updated>2025-03-12T12:01:13Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Considerations on Efficiency / Special Use Cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is not the number of cores of a node (see section [[#&amp;quot;Exclusive User&amp;quot; Node Access Policy]])&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
One-core jobs can cause major inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, start/finish of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many one-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and  the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same, but by tracking the PIDs (process IDs) of the started processes. This is more robust, but is more difficult to read:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily.&lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14318</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14318"/>
		<updated>2025-03-07T10:31:10Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Connect to Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
 &lt;br /&gt;
If you do note need much CPU ressources or memory. you can develop your code on the login nodes. If you however need more ressources, you must use an interactive job, see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How to submit an interactive job?]]. &lt;br /&gt;
&lt;br /&gt;
You can only connect to the compute nodes via a login node. Therefore you need to adjust your SSH config to use a login node for a proxy jump to the compute node, where your interactive job is running. Thus add the following lines to  $HOME/.ssh/config on your PC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host n????&lt;br /&gt;
        User    YOUR_JUSTUS_USERNAME&lt;br /&gt;
        ProxyJump justus2.uni-ulm.de&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please replace YOUR_JUSTUS_USENAME by your username on the cluster.&lt;br /&gt;
&lt;br /&gt;
To avoid to enter repeatedly your password, you should set up an SSH key to login.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14317</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14317"/>
		<updated>2025-03-07T10:29:43Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Connect to Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
 &lt;br /&gt;
If you do note need much CPU ressources or memory. you can develop your code on the login nodes. If you however need more ressources, you must use an interactive job, see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How to submit an interactive job?]]. &lt;br /&gt;
&lt;br /&gt;
You can only connect to the compute nodes via a login node. Therefore you need to adjust your SSH config to use a login node for a proxy jump to the compute node, where your interactive job is running. Thus add the following lines to  $HOME/.ssh/config on your PC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host n????&lt;br /&gt;
        User    YOUR_JUSTUS_USERNAME&lt;br /&gt;
        ProxyJump justus2.uni-ulm.de&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please replace YOUR_JUSTUS_USENAME by your username on the cluster.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14316</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14316"/>
		<updated>2025-03-07T10:28:02Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Connect to Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
 &lt;br /&gt;
If you do note need much CPU ressources or memory. you can develop your code on the login nodes. If you however need more ressources, you must use an interactive job, see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How to submit an interactive job?]]. &lt;br /&gt;
&lt;br /&gt;
You can only connect to the compute nodes via a login node. Therefore you need to adjust your SSH config, to use the login nodes for a proxy jump to the compute node, where your interactive job is running. This add the following lines to  $HOME/.ssh/config on your PC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Host n????&lt;br /&gt;
        User    YOUR_JUSTUS_USERNAME&lt;br /&gt;
        ProxyJump justus2.uni-ulm.de&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please replace YOUR_JUSTUS_USENAME by your username on the cluster.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14315</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14315"/>
		<updated>2025-03-07T10:19:38Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Connect to Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
 &lt;br /&gt;
If you do note need much CPU ressources or memory. you can develop your code on the login nodes. If you however need more ressources, you must use an interactive job, see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How to submit an interactive job?]]. &lt;br /&gt;
&lt;br /&gt;
# proxy jump&lt;br /&gt;
# SSH keys&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14312</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14312"/>
		<updated>2025-03-07T10:13:34Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Wrapper Script for Module Loading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
&lt;br /&gt;
# proxy jump&lt;br /&gt;
# SSH keys&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14310</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14310"/>
		<updated>2025-03-07T10:12:58Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Setting Up VS Code for Interactive Julia Sessions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
The Julia Extension of VS Code needs to run Julia, which requires loading the module. &lt;br /&gt;
&lt;br /&gt;
Save the following wrapper script e.g. as $HOME/bin/julia_wrapper.sh and make it executable:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
## Making module command available&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
export MODULEPATH=/opt/bwhpc/ul/modulefiles/Core:/opt/bwhpc/common/modulefiles/Core:/etc/modulefiles:/usr/share/modulefiles:/usr/share/modulefiles/Linux:/usr/share/modulefiles/Core:/usr/share/lmod/lmod/modulefiles/Core&lt;br /&gt;
&lt;br /&gt;
source /usr/share/lmod/lmod/init/profile&lt;br /&gt;
&lt;br /&gt;
## ------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Load julia&lt;br /&gt;
module load math/julia/1.11.3&lt;br /&gt;
&lt;br /&gt;
# Pass on all arguments to julia&lt;br /&gt;
exec julia &amp;quot;${@}&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next, we need to configure VSCode to use the script as Julia executable. You find the corresponding setting at File|Preferences|Settings → Tab “Remote” → Extensions|Julia → setting “Julia: Executable path“) &lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
&lt;br /&gt;
# proxy jump&lt;br /&gt;
# SSH keys&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14309</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14309"/>
		<updated>2025-03-07T10:00:16Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting Up VS Code for Interactive Julia Sessions =&lt;br /&gt;
&lt;br /&gt;
== Wrapper Script for Module Loading==&lt;br /&gt;
&lt;br /&gt;
== Connect to Nodes ==&lt;br /&gt;
&lt;br /&gt;
# proxy jump&lt;br /&gt;
# SSH keys&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14308</id>
		<title>JUSTUS2/Software/Julia/VSCode</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia/VSCode&amp;diff=14308"/>
		<updated>2025-03-07T09:57:58Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: Created page with &amp;quot;= Setting up VS Code for interactive Julia settings&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Setting up VS Code for interactive Julia settings&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14307</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14307"/>
		<updated>2025-03-07T09:48:59Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Monitoring a Started Job */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh from a login node to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is notthe number of cores of a node (see section on single user policy below)&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
One-core jobs can cause major inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, start/finish of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many one-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and  the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily. &lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14305</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14305"/>
		<updated>2025-03-07T09:47:08Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Memory Limits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
==  &amp;quot;Exclusive User&amp;quot; Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Nodes are exclusively allocated to one single user. However, multiple jobs (up to 48) from the same user can share a node.&lt;br /&gt;
&lt;br /&gt;
For efficient resource use, choose a core count for your jobs that evenly divides 48. For example, two 24-core jobs fit on one node, while two 32-core jobs require two nodes but leave 16 cores unused on each. &lt;br /&gt;
&lt;br /&gt;
The same applies to memory requests (see below).&lt;br /&gt;
&lt;br /&gt;
Think of scheduling as a game of Tetris with cores, memory, and other resources. Choosing well-fitting allocations helps the scheduler pack jobs efficiently.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The wait time of a job also depends largely on the amount of requested resources and the available number of nodes providing this amount of resources. This must be taken into account in particular when requesting a certain amount of memory.&lt;br /&gt;
&lt;br /&gt;
For example a node with 192 GB RAM can only run jobs with up to 187 GB memory requested. The remaining amount is reserved for the operating system, system services and local file systems.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), the job cannot run on one of the 456 &amp;quot;small&amp;quot; nodes but only on one of the  &amp;quot;medium&amp;quot;, &amp;quot;large&amp;quot; or &amp;quot;fat&amp;quot; nodes. Unnecessarily limiting your jobs to a sub-set of nodes will increase your wait time and the wait time of others, who actually need the amount of memory.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
|small| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
|medium| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
|large| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
|fat| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is notthe number of cores of a node (see section on single user policy below)&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
One-core jobs can cause major inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, start/finish of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many one-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and  the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily. &lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14296</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14296"/>
		<updated>2025-03-07T08:31:02Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;wait time of a job also depends largely on the amount of requested resources&#039;&#039;&#039; and the available number of nodes providing this amount of resources. This must be taken into account &#039;&#039;&#039;in particular when requesting a certain amount of memory&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For example, there is a total of 692 compute nodes in JUSTUS, of which 456 nodes have 192 GB RAM. However, &#039;&#039;&#039;not the entire amount of physical RAM is available exclusively for user jobs&#039;&#039;&#039;, because the operating system, system services and local file systems also require a certain amount of RAM.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), Slurm will rule out 456 out of 692 nodes as being suitable for this job and considers only 220 out of 692 nodes as being eligible for running this job.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
== Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Node access policy for jobs is &amp;quot;&#039;&#039;&#039;exclusive user&#039;&#039;&#039;&amp;quot;. Nodes will be exclusively allocated to users. &#039;&#039;&#039;Multiple jobs (up to 48) of the same user can run on a single node&#039;&#039;&#039; at any time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This implies that for &#039;&#039;&#039;sub-node jobs&#039;&#039;&#039;, it is advisable for efficient resource utilization and maximum job throughput to &#039;&#039;&#039;adjust the number of cores to be an integer divisor of 48&#039;&#039;&#039; (total number of cores on each node). For example, two 24-core jobs can run simultaneously on one and the same node, while two 32-core jobs will always have to allocate two separate nodes, but leave 16 cores unused on each of them. Users must therefore always &#039;&#039;&#039;think carefully about how many cores to request&#039;&#039;&#039; and whether their applications really benefit from allocating more cores for their jobs. Similar considerations apply - at the same time - to the &#039;&#039;&#039;requested amount of memory per job&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Think of it as the scheduler playing a game of multi-dimensional Tetris, where the dimensions are number of cores, amount of memory and other resources. &#039;&#039;&#039;Users can support this by making resource allocations that allow the scheduler to pack their jobs as densely as possible on the nodes&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is notthe number of cores of a node (see section on single user policy below)&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
One-core jobs can cause major inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, start/finish of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many one-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and  the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily. &lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14295</id>
		<title>JUSTUS2/Jobscripts: Running Your Calculations</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Jobscripts:_Running_Your_Calculations&amp;diff=14295"/>
		<updated>2025-03-07T08:29:06Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Justus2}}&lt;br /&gt;
&lt;br /&gt;
The JUSTUS 2 cluster uses Slurm ([https://slurm.schedmd.com/ https://slurm.schedmd.com/]) for scheduling compute jobs. &lt;br /&gt;
&lt;br /&gt;
= JUSTUS 2 Slurm Howto =&lt;br /&gt;
&lt;br /&gt;
This page only presents some very basic introduction. &lt;br /&gt;
&lt;br /&gt;
Please see  the &#039;&#039;&#039;[[bwForCluster JUSTUS 2 Slurm HOWTO|JUSTUS 2 Slurm HOWTO]]&#039;&#039;&#039; for many more examples and commands for common tasks.&lt;br /&gt;
&lt;br /&gt;
= Slurm Command Overview =&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Slurm commands !! Brief explanation&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sbatch.html sbatch] || Submits a job and queues it in an input queue&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/salloc.html salloc] || Request resources for an interactive job&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/squeue.html squeue] || Displays information about active, eligible, blocked, and/or recently completed jobs &lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/scontrol.html scontrol] || Displays detailed job state information&lt;br /&gt;
|-&lt;br /&gt;
| [https://slurm.schedmd.com/sstat.html sstat] || Displays status information about a running job&lt;br /&gt;
|- &lt;br /&gt;
| [https://slurm.schedmd.com/scancel.html scancel] || Cancels a job&lt;br /&gt;
|- &lt;br /&gt;
| seff  || Shows the &amp;quot;job efficiency&amp;quot; of a job after it has finished&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Submitting Jobs on the bwForCluster JUSTUS 2 =&lt;br /&gt;
Batch jobs are submitted with the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A job script contains options for Slurm in lines beginning with #SBATCH as well as your commands which you want to execute on the compute nodes. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can override options from the script on the command-line:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;$ sbatch --time=03:00:00 &amp;lt;job-script&amp;gt; &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Compute jobs must not write/read from the global file systems as a calculation swap file. &amp;lt;/font&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use local storage /tmp in the ramdisk for small files or /scratch (see [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_request_local_scratch_.28SSD.2FNVMe.29_at_job_submission.3F|How to request NVME]]) for this purpose&lt;br /&gt;
&lt;br /&gt;
To not use the central file system for calculation, you must often configure the the program you are using to write temporary files elsewhere. &lt;br /&gt;
&lt;br /&gt;
If the program uses the current directory to look for files, you must copy files to a temporary directory - and copy/save the results of the calculation in the end, else your results get deleted by automated cleanup happening after the job.&lt;br /&gt;
&lt;br /&gt;
There diskless nodes have a disk in RAM memory, that can have a maximum of half the size of the total RAM. Note that files created plus memory requirement of your job need to fit into the total memory. &lt;br /&gt;
&lt;br /&gt;
There are more diskless nodes than nodes with disks, so if your job can run on a diskless node, you should choose this option. &lt;br /&gt;
&lt;br /&gt;
Example job script with requesting 700GB disk space and copying files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;bash&#039;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --time=00:14:00&lt;br /&gt;
#SBATCH --mem=1gb&lt;br /&gt;
#SBATCH --gres=scratch:700 &lt;br /&gt;
# copy input file&lt;br /&gt;
cp $HOME/inputfiles/myinput.inp $SCRATCH&lt;br /&gt;
# switch directory&lt;br /&gt;
cd $SCRATCH&lt;br /&gt;
echo &#039;Here starts the calculation&#039;&lt;br /&gt;
myprogram --input=$SCRATCH/myinput.inp&lt;br /&gt;
# calculation ends&lt;br /&gt;
# copy result&lt;br /&gt;
cp outfile.out results2.txt $HOME/resultdir/job12345&lt;br /&gt;
# clean up&lt;br /&gt;
rm myinput outfile.out results2.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;  background:#deffee; width:100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;padding:12px; background:#cef2e0;  text-align:left&amp;quot; |&lt;br /&gt;
Software examples: Most [[Environment Modules|installed software]] comes with example job scripts. &amp;lt;br&amp;gt; To find it e.g. for lammps: &amp;lt;code&amp;gt; module load chem/lammps; cd $LAMMPS_EXA_DIR; ls -la&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Resource Requests ==&lt;br /&gt;
&lt;br /&gt;
Important resource request options for the Slurm command sbatch are:&lt;br /&gt;
&lt;br /&gt;
{| width=750px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Option !!  Slurm (sbatch)&lt;br /&gt;
|-&lt;br /&gt;
| #SBATCH|| Script directive&lt;br /&gt;
|-&lt;br /&gt;
| --time=&amp;lt;hh:mm:ss&amp;gt; (-t &amp;lt;hh:mm:ss&amp;gt;)|| Wall time limit&lt;br /&gt;
|-&lt;br /&gt;
| --job-name=&amp;lt;name&amp;gt;  (-J &amp;lt;name&amp;gt;)|| Job name&lt;br /&gt;
|-&lt;br /&gt;
| --nodes=&amp;lt;count&amp;gt; (-N &amp;lt;count&amp;gt;)|| Node count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks=&amp;lt;count&amp;gt; (-n &amp;lt;count&amp;gt;)|| Core count&lt;br /&gt;
|-&lt;br /&gt;
| --ntasks-per-node=&amp;lt;count&amp;gt;|| Process count per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem=&amp;lt;limit&amp;gt;|| Memory limit per node&lt;br /&gt;
|-&lt;br /&gt;
| --mem-per-cpu=&amp;lt;limit&amp;gt;|| Memory limit per process&lt;br /&gt;
|-&lt;br /&gt;
| --gres=gpu:&amp;lt;count&amp;gt;|| GPU count (gres = &amp;quot;generic resource&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| --gres=scratch:&amp;lt;count&amp;gt; || Disk space of &amp;lt;count&amp;gt; GB per requested task&lt;br /&gt;
|-&lt;br /&gt;
| --exclusive|| Node exclusive job&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nodes and Cores&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Slurm provides a number of options to request nodes and cores.&lt;br /&gt;
Typically, using &amp;lt;code&amp;gt;--nodes=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--ntasks-per-node=&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; should work for all your jobs. For single core jobs, it would be sufficient to use the option &amp;lt;code&amp;gt;--ntasks=1&amp;lt;/code&amp;gt;. Specifying only &amp;lt;code&amp;gt;--ntasks&amp;lt;/code&amp;gt; may lead to slurm trying to distribute tasks over more than one node even if you requested a small amount of cores.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Memory can be requested with either the option &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per node) or &amp;lt;code&amp;gt;--mem-per-cpu=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; (memory per process). When looking up the maximum available memory for a certain node type subtract about 5 GB for the operating system. Specify the memory limit as a value-unit-pair, for example 500mb or 8gb.&lt;br /&gt;
&lt;br /&gt;
In most cases it is preferable to use the &amp;lt;code&amp;gt;--mem=&amp;lt;limit&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GPUs&#039;&#039;&#039; and &#039;&#039;&#039;Scratch&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
These are requested as &amp;quot;generic resources&amp;quot; with &amp;lt;code&amp;gt;--gres:gpu:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;--gres:scratch:&amp;lt;count&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Memory Limits ==&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;wait time of a job also depends largely on the amount of requested resources&#039;&#039;&#039; and the available number of nodes providing this amount of resources. This must be taken into account &#039;&#039;&#039;in particular when requesting a certain amount of memory&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
For example, there is a total of 692 compute nodes in JUSTUS, of which 456 nodes have 192 GB RAM. However, &#039;&#039;&#039;not the entire amount of physical RAM is available exclusively for user jobs&#039;&#039;&#039;, because the operating system, system services and local file systems also require a certain amount of RAM.&lt;br /&gt;
This means that if a job requests 192 GB RAM per node (i.e. --mem=192gb or --tasks-per-node=48 and --mem-per-cpu=4gb), Slurm will rule out 456 out of 692 nodes as being suitable for this job and considers only 220 out of 692 nodes as being eligible for running this job.&lt;br /&gt;
&lt;br /&gt;
The following table provides an overview of how much memory can be allocated by user jobs on the various node types and how many nodes can serve this memory requirement:&lt;br /&gt;
&lt;br /&gt;
{| width=500px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Physical RAM on node !! Available RAM on node !! Number of suitable nodes &lt;br /&gt;
|-&lt;br /&gt;
| 192 GB || 187 GB || 692 &lt;br /&gt;
|-&lt;br /&gt;
| 384 GB || 376 GB || 220&lt;br /&gt;
|-&lt;br /&gt;
| 768 GB || 754 GB || 28&lt;br /&gt;
|-&lt;br /&gt;
| 1536 GB || 1510 GB || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also note that allocated memory is factored into resource usage accounting for fair share. This means over-requesting memory may have a negative impact on the priority of subsequent jobs.&lt;br /&gt;
&lt;br /&gt;
= Testing Your Jobs = &lt;br /&gt;
&lt;br /&gt;
Justus2 has three compute nodes reserved for jobs with a walltime under 15 minutes. You can test if your jobs start properly just by specifying a short walltime, e.g. --time=00:14:00 and your job should start very quickly. &lt;br /&gt;
&lt;br /&gt;
= Monitoring Your Jobs =&lt;br /&gt;
== squeue ==&lt;br /&gt;
&lt;br /&gt;
After you submitted the job, you can see it waiting using the &amp;lt;code&amp;gt;squeue&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
(also read the man page with &amp;lt;code&amp;gt;man squeue&amp;lt;/code&amp;gt; for more information on how to use the command)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&#039;shell&#039;&amp;gt;&lt;br /&gt;
&amp;gt; squeue&lt;br /&gt;
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)&lt;br /&gt;
             6260301  standard r_60_b_2 ul_yxz1 PD       0:00      1 (AssocGrpMemRunMinutes)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output shows: &lt;br /&gt;
* JOBID: the jobid is an unique number your job gets&lt;br /&gt;
* PARTITION: the cluster can be divided in different types of nodes.&lt;br /&gt;
* NAME: the name you gave your job with the --job-name= option&lt;br /&gt;
* USER: your username&lt;br /&gt;
* ST: the state the job is in. R = running, PD = pending, CD = completed. See man page for a full list on states. &lt;br /&gt;
* TIME: how long the job has been running&lt;br /&gt;
* NODES: how many nodes were requested&lt;br /&gt;
* NODELIST(REASON): either show the node(s) the job is running on, or a reason why it hasn&#039;t started&lt;br /&gt;
&lt;br /&gt;
==scontrol==&lt;br /&gt;
&lt;br /&gt;
You can then show more info on one specific running job using the &amp;lt;code&amp;gt;scontrol&amp;lt;/code&amp;gt; command, e.g for the job with ID 6260301 listed above:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show job 6260301&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for job with JobID 6260301&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
scontrol show jobs&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
displays detailed information for all your jobs&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
scontrol write batch_script 6260301 -&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
display job script of a running job. The &amp;quot;-&amp;quot; is a special filename which means &amp;quot;write to the terminal&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Monitoring a Started Job ==&lt;br /&gt;
&lt;br /&gt;
After a job has started, you can ssh to the node(s) the job is running on, using the node name from NODELIST, e.g. if your job runs on n0603:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;gt; ssh n0603 &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Partitions =&lt;br /&gt;
Job allocations at JUSTUS 2 are routed automatically to the most suitable compute node(s) that can provide the requested resources for the job (e.g. amount of cores, memory, local scratch space). This is to prevent fragmentation of the cluster system and to ensure most efficient usage of available compute resources. Thus, there is no point in requesting a partition in batch job scripts, i.e. users &#039;&#039;&#039;should not&#039;&#039;&#039; specify any partition &amp;quot;-p, --partition=&amp;lt;partition_name&amp;gt;&amp;quot; on job submission. This is of particular importance if you adapt job scripts from other cluster systems (e.g. bwUniCluster 2.0) to JUSTUS 2.&lt;br /&gt;
&lt;br /&gt;
= Job Priorities =&lt;br /&gt;
Job priorities at JUSTUS 2 depend on [https://slurm.schedmd.com/priority_multifactor.html multiple factors ]:&lt;br /&gt;
* Age: The amount of time a job has been waiting in the queue, eligible to be scheduled.&lt;br /&gt;
* Fairshare: The difference between the portion of the computing resource allocated to an association and the amount of resources that has been consumed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Jobs that are pending because the user reached one of the resource usage limits (see below) are not eligible to be scheduled and, thus, do not accrue priority by their age.  &lt;br /&gt;
&lt;br /&gt;
Fairshare does &#039;&#039;&#039;not&#039;&#039;&#039; introduce a fixed allotment, in that a user&#039;s ability to run new jobs is cut off as soon as a fixed target utilization is reached. Instead, the fairshare factor ensures that jobs from users who were under-served in the past are given higher priority than jobs from users who were over-served in the past. This keeps individual groups from long term monopolizing the resources, thus making it unfair to groups who have not used their fairshare for quite some time.&lt;br /&gt;
&lt;br /&gt;
Slurm features &#039;&#039;&#039;backfilling&#039;&#039;&#039;, meaning that the scheduler will start lower priority jobs if doing so does not delay the expected start time of &#039;&#039;&#039;any&#039;&#039;&#039; higher priority job. Since the expected start time of pending jobs depends upon the expected completion time of running jobs, reasonably accurate time limits are valuable for backfill scheduling to work well. This &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=161 video]&#039;&#039;&#039; gives an illustrative description to how backfilling works.&lt;br /&gt;
&lt;br /&gt;
In summary, an approximate model of Slurm&#039;s behavior for scheduling jobs is this:&lt;br /&gt;
&lt;br /&gt;
* Step 1: Can the job in position one (highest priority) start now?&lt;br /&gt;
* Step 2: If it can, remove it from the queue, start it and continue with step 1.&lt;br /&gt;
* Step 3: If it can not, look at next job.&lt;br /&gt;
* Step 4: Can it start now, without delaying the start time of any job before it in the queue?&lt;br /&gt;
* Step 5: If it can, remove it from the queue, start it, recalculate what nodes are free, look at next job and continue with step 4.&lt;br /&gt;
* Step 6: If it can not, look at next job, and continue with step 4.&lt;br /&gt;
&lt;br /&gt;
As soon as a new job is submitted and as soon as a job finishes, Slurm restarts its main scheduling cycle with step 1.&lt;br /&gt;
&lt;br /&gt;
= Usage Limits/Throttling Policies =&lt;br /&gt;
&lt;br /&gt;
While the fairshare factor ensures fair long term balance of resource utilization between users and groups, there are additional usage limits that constrain the total cumulative resources at a given time. This is to prevent individual users from short term monopolizing large fractions of the whole cluster system.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum walltime&#039;&#039;&#039; for a job is &#039;&#039;&#039;14 days&#039;&#039;&#039; (336 hours)&lt;br /&gt;
  --time=336:00:00 or --time=14-0&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of cores&#039;&#039;&#039; used at any given time from jobs running is &#039;&#039;&#039;1920&#039;&#039;&#039; per user (aggregated over all running jobs). This translates to 40 nodes. An equivalent limit for allocated memory does also apply. If this limit is reached new jobs will be queued (with REASON: AssocGrpCpuLimit) but only allowed to run after resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
* The maximum amount of &#039;&#039;&#039;remaining allocated core-minutes&#039;&#039;&#039; per user is &#039;&#039;&#039;3300000&#039;&#039;&#039; (aggregated over all running jobs). For example, if a user has a 4-core job running that will complete in 1 hour and a 2-core job that will complete in 6 hours, this translates to 4 * 1 * 60 + 2 * 6 * 60 = 16 * 60 = 960 remaining core-minutes. Once a user reaches the limit, no more jobs are allowed to start (REASON: AssocGrpCPURunMinutesLimit). As the jobs continue to run, the remaining core time will decrease and eventually allow more jobs to start in a staggered way. This limit also &#039;&#039;&#039;correlates the maximum walltime and amount of cores that can be allocated&#039;&#039;&#039; for this amount of time. Thus, shorter walltimes for the jobs allow more resources to be allocated at a given time (but capped by the maximum amount of cores limit above). Watch this &#039;&#039;&#039;[https://youtu.be/OKhWwem1XZg?t=306 video]&#039;&#039;&#039; for an illustrative description. An equivalent limit applies for remaining time of memory allocation in which case jobs may be held back from starting with REASON AssocGrpMemRunMinutes.&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;maximum amount of GPUs&#039;&#039;&#039; allocated by running jobs is &#039;&#039;&#039;8&#039;&#039;&#039; per user. If this limit it reached new jobs will be queued (with REASON: AssocGrpGRES) but only allowed to run after GPU resources have been relinquished. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Usage limits are subject to change.&lt;br /&gt;
&lt;br /&gt;
= Considerations on Efficiency / Special Use Cases =&lt;br /&gt;
&lt;br /&gt;
When we speak of poor job efficiency, we usually mean that hardware resources are wasted.&lt;br /&gt;
That means, a similar overall result could have been achieved using less hardware resources, leaving those for other jobs and reducing the wait time for you and everyone.&lt;br /&gt;
&lt;br /&gt;
Some simple causes for poor overall job efficiency are:&lt;br /&gt;
&lt;br /&gt;
*    poor choice of resources compared to the size of the nodes leaves part of the node blocked, but doing nothing:&lt;br /&gt;
** multiple of --ntasks-per-node is notthe number of cores of a node (see section on single user policy below)&lt;br /&gt;
** too much (un-needed) memory or disk space requested&lt;br /&gt;
*    more cores requested than are actually used by the job&lt;br /&gt;
*    more cores used for a single mpi/openmp parallel computation than useful&lt;br /&gt;
*    many small jobs with a short runtime (seconds in extreme cases)&lt;br /&gt;
*    one-core jobs with very different run-times (because of single-user policy)&lt;br /&gt;
&lt;br /&gt;
== Many One-Core Jobs ==&lt;br /&gt;
&lt;br /&gt;
One-core jobs can cause major inefficient node usage:&lt;br /&gt;
&lt;br /&gt;
# You submit 1000 jobs, each runs for ~30s.  Jobs need up to 30s to start and finish - a huge waste if the job only takes 30 seconds. Additionally, start/finish of so many jobs in a short time causes strain on the scheduler SLURM and may cause severe problems for everyone and clutter the SLURM job database. &lt;br /&gt;
# many one-core jobs with very different run times. The jobs will start on many nodes, but at some time all quicker jobs have finished the calculation and only a few remain. Because of the single-user policy on JUSTUS2, jobs of other users cannot fill in the gaps and  the rest of the node is idle. &lt;br /&gt;
&lt;br /&gt;
To address the problem, you can reduce the amount of jobs and/or the amount of nodes used.&lt;br /&gt;
&lt;br /&gt;
To limit the amount of jobs, start many calculations within one job (problem 1. and 2.):&lt;br /&gt;
&lt;br /&gt;
* use a bash loop in your job script&lt;br /&gt;
* use the program GNU parallel to start the processes for you&lt;br /&gt;
&lt;br /&gt;
To only limit the amount of nodes used:&lt;br /&gt;
&lt;br /&gt;
* use array jobs&lt;br /&gt;
&lt;br /&gt;
=== Bash Loop ===&lt;br /&gt;
&lt;br /&gt;
One advantage of this method is, that you can run more threads than cores if your jobs are really short and do not use too much RAM memory and in this way keep all cores busy even if many calculations are still starting up.&lt;br /&gt;
&lt;br /&gt;
It is of course even better, if you can combine such short calculations in a way that for 1000 calculations the kernel does not need to start 1000 processes which in turn need to initialize everything. &lt;br /&gt;
&lt;br /&gt;
This example uses pgrep to count how many jobs are running: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#SBATCH --nodes=1&lt;br /&gt;
#SBATCH --ntasks-per-node=48&lt;br /&gt;
#SBATCH --time=00:10:00&lt;br /&gt;
#SBATCH --mem=100gb&lt;br /&gt;
 &lt;br /&gt;
for i in {1..200}&lt;br /&gt;
do&lt;br /&gt;
  echo starting up $i&lt;br /&gt;
   bash my_calculation $i  &amp;amp;&lt;br /&gt;
   while [ $(pgrep -c -f my_calculation) -gt 48 ] ; do echo sleeping; sleep 5; done&lt;br /&gt;
done&lt;br /&gt;
wait&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
running_jobs=()&lt;br /&gt;
&lt;br /&gt;
for i in {1..200}; do&lt;br /&gt;
  echo &amp;quot;Starting job $i&amp;quot;&lt;br /&gt;
  sleep &amp;quot;$i&amp;quot; &amp;amp;  &lt;br /&gt;
  running_jobs+=($!)  # Track PID&lt;br /&gt;
&lt;br /&gt;
  while [ &amp;quot;${#running_jobs[@]}&amp;quot; -ge 8 ]; do&lt;br /&gt;
    sleep 2 # adjust duration depending on your runtime&lt;br /&gt;
    echo running_jobs: ${running_jobs[@]} &lt;br /&gt;
    echo pid-out: $(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null | xargs)&lt;br /&gt;
    echo -----&lt;br /&gt;
    running_jobs=($(ps -o pid= -p &amp;quot;${running_jobs[@]}&amp;quot; 2&amp;gt;/dev/null))  # Remove finished jobs&lt;br /&gt;
  done&lt;br /&gt;
done&lt;br /&gt;
&lt;br /&gt;
wait  # Ensure all jobs complete&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not be able to just use an index number &amp;quot;i&amp;quot; to start many calculations. In this case, for not too many files, the for loop could be used to read in config files. Here just the general idea for the for loop without &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
for config in config-1980-03-01_1/*; do&lt;br /&gt;
  mycalculation -config &amp;quot;$config&amp;quot;&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This loops over all files in the directory config-1980-03-01_1/ and gives them as an input file to &amp;quot;mycalculation&amp;quot; via a hypothetical &amp;quot;-config&amp;quot; option. Adding a date to the config-dirs (and outputs) would enable you to track different runs in your lab journal more easily. &lt;br /&gt;
&lt;br /&gt;
=== Gnu Parallel ===&lt;br /&gt;
&lt;br /&gt;
Gnu Parallel is available on the HPC Cluster and comes with its own set of examples, you can access them like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ module load system/parallel&lt;br /&gt;
$ cp $PARALLEL_EXA_DIR/parallel.slurm .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Array Jobs ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;$ sbatch -a 1-500%48 batch_script&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will submit 500 tasks to be executed, each one indexed by SLURM_ARRAY_TASK_ID ranging from 1 to 200, but will limit the number of simultaneously running tasks from this job array to 48 (number of cores on a Justus2 node).&lt;br /&gt;
&lt;br /&gt;
Thee same can be done inside the job script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
# Number of cores per individual array task&lt;br /&gt;
#SBATCH --ntasks-per-node=1&lt;br /&gt;
#SBATCH --array=1-500%48&lt;br /&gt;
#SBATCH --mem=3G&lt;br /&gt;
#SBATCH --time=1:10:00&lt;br /&gt;
#SBATCH --job-name=array_job&lt;br /&gt;
#SBATCH --output=array_job-%A_%a.out&lt;br /&gt;
#SBATCH --error=array_job-%A_%a.err&lt;br /&gt;
 &lt;br /&gt;
# Print the task id.&lt;br /&gt;
echo &amp;quot;My SLURM_ARRAY_TASK_ID: &amp;quot; $SLURM_ARRAY_TASK_ID&lt;br /&gt;
 &lt;br /&gt;
export  TIMEFORMAT=%R ; &lt;br /&gt;
time bash mycalculation $SLURM_ARRAY_TASK_ID&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also see: &lt;br /&gt;
* Slurm-Howto entry: [[BwForCluster_JUSTUS_2_Slurm_HOWTO#How_to_submit_an_array_job?]]&lt;br /&gt;
* Schedmd documentations on Job Arrays: https://slurm.schedmd.com/job_array.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Default Values ==&lt;br /&gt;
&lt;br /&gt;
Default values for jobs are:&lt;br /&gt;
&lt;br /&gt;
* Runtime: --time=02:00:00 (2 hours)&lt;br /&gt;
* Nodes: --nodes=1 (one node)&lt;br /&gt;
* Tasks: --tasks-per-node=1 (one task per node)&lt;br /&gt;
* Cores: --cpus-per-task=1 (one core per task)&lt;br /&gt;
* Memory: --mem-per-cpu=2gb (2 GB per core)&lt;br /&gt;
&lt;br /&gt;
== Node Access Policy ==&lt;br /&gt;
&lt;br /&gt;
Node access policy for jobs is &amp;quot;&#039;&#039;&#039;exclusive user&#039;&#039;&#039;&amp;quot;. Nodes will be exclusively allocated to users. &#039;&#039;&#039;Multiple jobs (up to 48) of the same user can run on a single node&#039;&#039;&#039; at any time.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This implies that for &#039;&#039;&#039;sub-node jobs&#039;&#039;&#039;, it is advisable for efficient resource utilization and maximum job throughput to &#039;&#039;&#039;adjust the number of cores to be an integer divisor of 48&#039;&#039;&#039; (total number of cores on each node). For example, two 24-core jobs can run simultaneously on one and the same node, while two 32-core jobs will always have to allocate two separate nodes, but leave 16 cores unused on each of them. Users must therefore always &#039;&#039;&#039;think carefully about how many cores to request&#039;&#039;&#039; and whether their applications really benefit from allocating more cores for their jobs. Similar considerations apply - at the same time - to the &#039;&#039;&#039;requested amount of memory per job&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Think of it as the scheduler playing a game of multi-dimensional Tetris, where the dimensions are number of cores, amount of memory and other resources. &#039;&#039;&#039;Users can support this by making resource allocations that allow the scheduler to pack their jobs as densely as possible on the nodes&#039;&#039;&#039;.&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13551</id>
		<title>JUSTUS2/Software/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13551"/>
		<updated>2025-01-07T08:56:08Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Further documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Softwarepage|math/julia}}&lt;br /&gt;
&lt;br /&gt;
{| width=600px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Description !! Content&lt;br /&gt;
|-&lt;br /&gt;
| module load&lt;br /&gt;
| math/julia&lt;br /&gt;
|-&lt;br /&gt;
| Availability&lt;br /&gt;
| [[bwUniCluster]] &amp;amp;#124; [[JUSTUS2]]&lt;br /&gt;
|-&lt;br /&gt;
| License&lt;br /&gt;
| MIT License&lt;br /&gt;
|-&lt;br /&gt;
|Citing&lt;br /&gt;
| [https://github.com/JuliaLang/julia/blob/master/CITATION.bib]&lt;br /&gt;
|-&lt;br /&gt;
| Links&lt;br /&gt;
| [https://julialang.org/ Project homepage] &amp;amp;#124; [https://docs.julialang.org/en/v1/ Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Graphical Interface&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exit packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.   &lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]: A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13550</id>
		<title>JUSTUS2/Software/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13550"/>
		<updated>2025-01-07T08:55:59Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Further documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Softwarepage|math/julia}}&lt;br /&gt;
&lt;br /&gt;
{| width=600px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Description !! Content&lt;br /&gt;
|-&lt;br /&gt;
| module load&lt;br /&gt;
| math/julia&lt;br /&gt;
|-&lt;br /&gt;
| Availability&lt;br /&gt;
| [[bwUniCluster]] &amp;amp;#124; [[JUSTUS2]]&lt;br /&gt;
|-&lt;br /&gt;
| License&lt;br /&gt;
| MIT License&lt;br /&gt;
|-&lt;br /&gt;
|Citing&lt;br /&gt;
| [https://github.com/JuliaLang/julia/blob/master/CITATION.bib]&lt;br /&gt;
|-&lt;br /&gt;
| Links&lt;br /&gt;
| [https://julialang.org/ Project homepage] &amp;amp;#124; [https://docs.julialang.org/en/v1/ Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Graphical Interface&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exit packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.   &lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows] A collection of best practices &lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
	<entry>
		<id>https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13549</id>
		<title>JUSTUS2/Software/Julia</title>
		<link rel="alternate" type="text/html" href="https://wiki.bwhpc.de/wiki/index.php?title=JUSTUS2/Software/Julia&amp;diff=13549"/>
		<updated>2025-01-07T08:54:54Z</updated>

		<summary type="html">&lt;p&gt;M Carmesin: /* Further documentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Softwarepage|math/julia}}&lt;br /&gt;
&lt;br /&gt;
{| width=600px class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Description !! Content&lt;br /&gt;
|-&lt;br /&gt;
| module load&lt;br /&gt;
| math/julia&lt;br /&gt;
|-&lt;br /&gt;
| Availability&lt;br /&gt;
| [[bwUniCluster]] &amp;amp;#124; [[JUSTUS2]]&lt;br /&gt;
|-&lt;br /&gt;
| License&lt;br /&gt;
| MIT License&lt;br /&gt;
|-&lt;br /&gt;
|Citing&lt;br /&gt;
| [https://github.com/JuliaLang/julia/blob/master/CITATION.bib]&lt;br /&gt;
|-&lt;br /&gt;
| Links&lt;br /&gt;
| [https://julialang.org/ Project homepage] &amp;amp;#124; [https://docs.julialang.org/en/v1/ Documentation]&lt;br /&gt;
|-&lt;br /&gt;
| Graphical Interface&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Julia is a high-level, high-performance, dynamic programming language, being designed with scientific computing in mind. Parallel programming features, such as multi-threading are included in the core language, while there also exit packages leveraging the power of MPI and CUDA.&lt;br /&gt;
&lt;br /&gt;
There are no packages preinstalled besides the Julia language core, please use the Julia package manager to install any required Julia package.&lt;br /&gt;
&lt;br /&gt;
The Julia module on Justus loads suitable versions of CUDA and OpenMPI and the corresponding Julia packages CUDA.jl and MPI.jl will be automatically configured to use these libraries after being installed by the user. Any changes, either by loading modules with different MPI and/ or CUDA versions as well as using the ones that come as Julia artifacts are likely to lead to errors.   &lt;br /&gt;
&lt;br /&gt;
== Environments and Package Installation ==&lt;br /&gt;
&lt;br /&gt;
It is highly recommended to use an separate Julia environment for every project. If Julia is started with the option &amp;lt;code&amp;gt;--project=.&amp;lt;/code&amp;gt; the current folder will be used as environment and the &amp;lt;code&amp;gt;Project.toml&amp;lt;/code&amp;gt; file containing the information on the installed packages will be created, if not yet present. &lt;br /&gt;
&lt;br /&gt;
In an interactive Julia session, the [https://pkgdocs.julialang.org/v1/getting-started/#Basic-Usage package manager] is activated by entering &amp;lt;code&amp;gt;]&amp;lt;/code&amp;gt;. The most importent commands are&lt;br /&gt;
* &amp;lt;code&amp;gt;add PACKAGENAME&amp;lt;/code&amp;gt; install package PACKAGENAME in the current environment &lt;br /&gt;
* &amp;lt;code&amp;gt;instantiate&amp;lt;/code&amp;gt;: install all packages with dependencies as stated in Project.toml and Manifest.toml, e.g. after copying the existing code to the cluster&lt;br /&gt;
* &amp;lt;code&amp;gt;activate PATH_TO_ENV&amp;lt;/code&amp;gt;: use the environment located at the path &amp;lt;code&amp;gt;PATH_TO_ENV&amp;lt;/code&amp;gt; and initialize it, if necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interactive Example ==&lt;br /&gt;
&lt;br /&gt;
Load Julia module and start interactive REPL session with 8 threads, using the environment in the current directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ module load math/julia&lt;br /&gt;
$ julia -t 8 --project=.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Enter &#039;]&#039; to go into package manager and install package [https://github.com/JuliaPlots/UnicodePlots.jl?tab=readme-ov-file &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt;].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add UnicodePlots&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Leave the package manager with the backspace key.&lt;br /&gt;
&lt;br /&gt;
Create a vector with 64 elements set to 0 and fill it using all 8 threads with the corresponding tread id number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
vec = zeros(64)&lt;br /&gt;
Threads.@threads for i in eachindex(vec)&lt;br /&gt;
    vec[i]= Threads.threadid()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Load the &amp;lt;code&amp;gt;UnicodePlots&amp;lt;/code&amp;gt; package and draw a scatter plot of the contents of &amp;lt;code&amp;gt;vec&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
using UnicodePlots&lt;br /&gt;
scatterplot(vec)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Further documentation ==&lt;br /&gt;
&lt;br /&gt;
* [https://modernjuliaworkflows.org Modern Julia Workflows]&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/carstenbauer/JuliaHLRS24 Julia Workshop at HLRS]: The material of this workshop is in large parts also valid for the Justus cluster (on Justus you only need the module math/julia).&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[JUSTUS2/Software/Julia/Parallel_Programming|Parallel Programming]]&lt;/div&gt;</summary>
		<author><name>M Carmesin</name></author>
	</entry>
</feed>