Another option is to use placement sets. There are several uses of placement sets, but your use case was the original one (network topology).
It works kind of like how @adarsh said, but instead of having to request a particular region, the scheduler does it for you. The idea is that you don’t care which region you run in, but you want all the nodes assigned to your job in the same region.
To do this, set up the string array resource like he suggested.
Then set the following:
qmgr -c ‘s s node_group_key=region’
qmgr -c ‘s s node_group_enable=true’
Placement sets are sorted by size (ncpus/men). You will see your jobs fill up one placement set before it moves onto the next.
Placement sets can overlap. This means if you have smaller topology inside inside of a larger region, you can create all the smaller placement sets to overlap with the larger region sets.
Something like this:
P1: N1, N2
P2: N3, N4
R1: N1, N2, N3, N4
P3: N5, N6
P4: N7, N8
R2: N5, N6, N7, N8
The scheduler will run jobs on the smaller PN placement sets first before trying to run them on the larger ones. As a note, this will require setting up two different placement set resources (like region). One will be fore the P placement sets, and the other will be for the R placement sets.
One thing to note is that there is a case where you can cross regions. This happens when a job cannot run in any defined placement set. Think about if a job requested 5 nodes in the above example. The largest set is 4 nodes, so in that case the scheduler will run the job wherever it can.
There is nothing stopping you from combining what @ardash said and placement sets. You can set up placement sets for most people to use, but if someone really wants to run in europe, they can request region=europe like ardash said.