Search code examples
c#.netazureazure-batch

How can I programmatically get the number of cores in an Azure Batch Node?


We are using the Azure Batch service to run some computation engine code, and we specify the size of of the VM when we create the pool:

var pool = batchClient.PoolOperations.CreatePool(poolId: $"{PoolIdPrefix}-{poolGuid}", virtualMachineSize: "STANDARD_G4", cloudServiceConfiguration: new CloudServiceConfiguration(osFamily: "4"), targetDedicatedComputeNodes: 31, targetLowPriorityComputeNodes: 0);

Note: The targetDedicatedComputeNodes is currently hardcoded, but will be changed once this problem is fixed.

Using this, we decide the Virtual Machine size, which in this case, happens to have 16 cores.

The issue is, prior to this code executing, we need to check the currently existing pools and calculate (or preferably simply read) how many cores are currently in use to know when we can create another pool with its desired amount of cores (and thus nodes).

An example would be if we have a limit of 160 cores (so 10 nodes with this configuration) and we want to create a pool that uses 120 cores for itself and then right after that pool is created and starts executing we have another pool that wants to be created. This new pool also wants 120 cores, so we need to be able to tell the new pool to wait because there are not enough cores left for it to be made.

I have found a way to get the number of ComputeNodes in use using the following code:

var batchManagementClient = new BatchManagementClient(new TokenCredentials(token))
{
    SubscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
};

var currentNodes = 0;
using (var batchClient = BatchClient.Open(credentials))
{
    var pools = batchClient.PoolOperations.ListPools();
    foreach (var cloudPool in pools)
    {
        if (cloudPool.CurrentDedicatedComputeNodes != null)
        {
            currentNodes += cloudPool.CurrentDedicatedComputeNodes.Value;
        }
    }
}

The problem here though is that ComputeNodes don't have any properties that tell me how many cores it has/is using, and I have yet to find any ManagementClient-like class, or any other class or method, to get either the number of cores in use in a given pool, or all pools, or how many cores a single ComputeNode has assigned to it.

Alternatively, I have not found a way to get the number of cores that would be assigned to each ComputeNode based on the virtualMachineSize property that we use when we create a new pool either.

Any help with this would be appreciated, as I would rather get the number of cores in code to protect from any size changes Microsoft may make in the future regarding virtualMachineSize because I would otherwise have to hard code the number of cores based on our specified VM size.

Note: There appears to be a Powershell CMDlet that gets both the currently used cores and the limit of usable cores for all the pools in a given location, and the Azure Portal Pool blade shows a table that has a selectable column that reports currently used cores. So I would think this should be possible in C# as well.

Please let me know if there is any other information I can provide.

Thanks.


Solution

  • You can do this by combining the Azure Batch .NET SDK as you are using it above with the Azure Management .NET SDK. Optionally, you can get your core quota for your Batch account on-demand using the Azure Batch Management .NET SDK.

    1. First get a list of your CloudPools in your account.
    2. For each Batch pool in your account, get the VirtualMachineSize string and the CurrentDedicatedComputeNodes count. Note that Dedicated counts are separate from Low Priority counts (and quotas).
    3. Get a list of VirtualMachineSizes for the region that your Batch account is in using the Azure Management SDK (Compute). This will return an iterable list of VirtualMachineSize, for which you can get the numberOfCores for the corresponding VirtualMachineSize as correlated against #2.
    4. Compute result of SumAllBatchPools(VirtualMachineSize.numberOfCores * CurrentDedicatedComputeNodes)
    5. Optionally query your Batch Account core quota using the Azure Batch Management .NET API and compute the difference from #5 to get your instantaneous available core quota for your Batch account.