-
Notifications
You must be signed in to change notification settings - Fork 199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for node resource hints in provider #942
Comments
Note already have |
This is high priority for QCArchive. |
The quickest way to go about this would be to specify exactly the resource slice you need from the scheduler, via Parsl's Here's a sample config that would work after we've got the bits implemented : HighThroughputExecutor(
label="htex",
cores_per_worker=2,
mem_per_worker=2, # 2GB
provider=SlurmProvider(
'debug',
nodes_per_block=2,
scheduler_options = '#SBATCH --cpus-per-task=2 --mem-per-cpu=1g --ntasks=1',
worker_init='export PARSL_MAX_MEMORY=2G; export PARSL_MAX_CPUS=2',
)
) |
It would be good if the scheduler options where taken care of automatically by the general |
This commit adds support for respecting specification of how much CPU and memory should be used by workers via the PARSL_CORES and PARSL_GB_MEMORY environmental variables (as opposed to inferring it to be the full node, once a job has started on the node.) After this commit, the config below should work to submit two two-core workers. This is a pre-requisite to a full solution to #942. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=2, mem_per_worker=2, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', cmd_timeout=60, nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, scheduler_options='#SBATCH --cpus-per-task=2 --mem-per-cpu=1g, worker_init='export PARSL_GB_MEMORY=4; export PARSL_CORES=4', exclusive=False ), ) ], ) ```
This commit adds support for respecting specification of how much CPU and memory should be used by workers via the PARSL_CORES and PARSL_GB_MEMORY environmental variables (as opposed to inferring it to be the full node, once a job has started on the node.) After this commit, the config below will result in 4 workers being started, using a total of 4 cores and 12 GB memory. This is a pre-requisite to a full solution to #942. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=1, mem_per_worker=3, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', cmd_timeout=60, nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, scheduler_options='#SBATCH --cpus-per-task=4 --mem-per-cpu=3g, worker_init='worker_init='export PARSL_GB_MEMORY=$(expr $SLURM_CPUS_ON_NODE \* $SLURM_MEM_PER_CPU); export PARSL_CORES=$SLURM_CPUS_ON_NODE', exclusive=False ), ) ], ) ```
…sl into support-env-resource-spec-#942
* Support cpu and mem specification via env This commit adds support for respecting specification of how much CPU and memory should be used by workers via the PARSL_CORES and PARSL_GB_MEMORY environmental variables (as opposed to inferring it to be the full node, once a job has started on the node.) After this commit, the config below will result in 4 workers being started, using a total of 4 cores and 12 GB memory. This is a pre-requisite to a full solution to #942. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=1, mem_per_worker=3, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', cmd_timeout=60, nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, scheduler_options='#SBATCH --cpus-per-task=4 --mem-per-cpu=3g, worker_init='worker_init='export PARSL_MEMORY_GB=$(expr $SLURM_CPUS_ON_NODE \* $SLURM_MEM_PER_CPU); export PARSL_CORES=$SLURM_CPUS_ON_NODE', exclusive=False ), ) ], ) ``` * Change PARSL_GB_MEMORY -> PARSL_MEMORY_GB * Revert changes to launchers This reversts the launcher changes introduced in 18061d2.
This commit adds the `cores_per_node` and `mem_per_node` keyword args to the SlurmProvider. These default to None, and behavior is not modified in the default case. Setting either has three effects. First, it modifies the Slurm submit script to request the appropriate cores and/or memory. Second, it sets the environment variables `PARSL_MEMORY_GB` and `PARSL_CORES` on the node. Finally, the HighThroughputExecutor is modified to respect those environment variables if they are set, instead of assuming it has the entire node available for starting workers. An example configuration, tested on Midway, is provided below. This configuration requests 4 1-core workers, each with 3 GB of memory. Partially addresses #942. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=1, mem_per_worker=3, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, mem_per_node=12, cores_per_node=4, exclusive=False ), ) ], ) ```
Partially addresses #942. This commit adds the `cores_per_node` and `mem_per_node` keyword args to the SlurmProvider. These default to None, and behavior is not modified in the default case. Setting either has three effects. First, it modifies the Slurm submit script to request the appropriate cores and/or memory. Second, it sets the environment variables `PARSL_MEMORY_GB` and `PARSL_CORES` on the node. Finally, the `workers_per_node` attribute is added to the `HighThroughputExecutor` which will be calculated according to the resource hints, if they are available. This is read by the strategy piece, enabling a more accurate calculation for scaling resources up and down. An example configuration, tested on Midway, is provided below. This configuration requests 4 1-core workers, each with 3 GB of memory. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=1, mem_per_worker=3, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, mem_per_node=12, cores_per_node=4, exclusive=False ), ) ], ) ```
* Implement resource hints for the SlurmProvider Partially addresses #942. This commit adds the `cores_per_node` and `mem_per_node` keyword args to the SlurmProvider. These default to None, and behavior is not modified in the default case. Setting either has three effects. First, it modifies the Slurm submit script to request the appropriate cores and/or memory. Second, it sets the environment variables `PARSL_MEMORY_GB` and `PARSL_CORES` on the node. Finally, the `workers_per_node` attribute is added to the `HighThroughputExecutor` which will be calculated according to the resource hints, if they are available. This is read by the strategy piece, enabling a more accurate calculation for scaling resources up and down. An example configuration, tested on Midway, is provided below. This configuration requests 4 1-core workers, each with 3 GB of memory. ``` from parsl.config import Config from parsl.providers import SlurmProvider from parsl.addresses import address_by_hostname from parsl.executors import HighThroughputExecutor config = Config( executors=[ HighThroughputExecutor( cores_per_worker=1, mem_per_worker=3, address=address_by_hostname(), provider=SlurmProvider( 'broadwl', nodes_per_block=1, init_blocks=1, min_blocks=1, max_blocks=1, mem_per_node=12, cores_per_node=4, exclusive=False ), ) ], ) ``` * Add default mem_per_node and cores_per_node * Switch to properties in base class Also: clarify docstrings. * Fix flake8 Also: fix incomplete conversion to property. * Fix setter definition
This has been implemented for the This hasn't made it into a release yet, but you can install the lastest with: Here's a config I tested with:
|
I'll be able to test this tomorrow! Is this tech going to go into the other providers as well such as the |
@Lnaden Sure thing, we can add it to |
Perfectly fine with that. This should be awesome if working correctly. I'll give it a test tomorrow and get back to you! |
Awesome. This appears to be working thus far as intended. Exclusive mode still works (requests all the cpus) but does restrict memory as expected. This allows me to queue up multiple blocks on the same node and for our use case we only ever have our blocks stretch one node anyways. From our use case perspective, this appears to be working the way we would need it to. I have not tested oversubscribing the cores per worker > cores_per_node * nodes_per_block as thats not one of our uses cases (and we block users from doing so anyways). I have also not tested multi-node jobs since we don't need that at the moment either. I can do more extensive testing, but it will take some additional time. The only bug I found was that the Overall, this appears to be exactly what we needed! Great work! |
I should also clarify that non-exclusive mode works just fine as well, which is the point. |
@Lnaden great, thanks for the bug report and the testing! Which other providers are your highest-priority to get this into first? |
If I had to order them in priority of this implementation:
I do know that because we use the |
Great to hear. I'll be able to test the first two on my own when they are available, I'll have to enlist some help for the
Good to know. When that comes up, I'll be able to test it more. Do you happen to know if there is a quick command to check which flavor of PBS/Torque a user has installed for future reference? |
With IPP we had to explicitly specify the number of workers to be launched per node, since the launch system doesn't necessarily run on the compute node and lacked information about the available resource before hand. As we developed HTEX, we moved to an architecture where we might use a launch system that starts 1 manager per node, and this manager after probing available cpu/mem/ resources on the node launches workers based on per-worker resource limits set by the user. This only helps once we have a node provisioned and doesn't help in the strategy planning phase where resource information is still unavailable and we assume the worst case, only 1 worker can run per node, leading to gross overestimation of resources required. One potential automatic method would be to launch a single block and wait until resource information is available before attempting to scale further, but this might work poorly with slow queues. This would definitely take more effort, and is better done with the plan to revamp the strategy component.
When all else fails, we could fallback to the user to specify resource hints to the provider :
This is a MolSSI/QCArchive requirement (@Lnaden)
The text was updated successfully, but these errors were encountered: