Resources
- class sane.resources.Resource[source]
A quantifiable positive integer resource
Resourceis a wrapper class on quatifiable values to facilitate common operations such as basic arithmetic, reduction to human-readable scaled units (in binary metric prefix, e.g. kibi, mebi, etc.), and type-checking operations between matching resource types or scalars.Resource.amountcan be set to anything that follows the following regular expression:(\d+)(k|m|g|t)?(b|w)?The first capture group (1st set of parenthesis) expects any number of numeric literals.The second capture group (2nd set of parenthesis) optionally can be a binary scaleThe third capture group (3rd set of parenthesis) optionally can be a unit (limited to ‘b’ or ‘w’ currently)Examples of valid and invalid resource amounts:
# valid 1 8k 512mb # invalid 1.0 -2 7.6gw
All supported binary operations on a
Resourcereturn a newResourcewith the resultantamountexcept the division of two resources which results in anintvalue. The following operations are supported:res_a = sane.resource.Resource( "mem", "4gb" ) res_b = sane.resource.Resource( "mem", "2gb" ) # addition and subtraction res_a + res_b or res_a - res_b res_a + 12345 or res_a - 12345 # multiplication and division res_a * 2 or res_a / 2 res_a / res_b # Note: This results in an int and mult is not supported res_c = sane.resource.Resource( "cpus", 12 ) # Unsupported operations res_a + res_c # incompatible resouce type res_a + 1.2345 # float add/sub res_a - 1.2345 # float add/sub res_a * res_b # undefined behavior res_a - ( res_a * 2 ) # negative amount not allowed
Note
Resource.amountmust be an integer value, even if scaled. Thetotalorcurrentvalues will always be integer values, even if unscaled or multiplied/divided by afloatvalue.Scaling amounts:
prefix
multiplier
k1024
m1024 2
g1024 3
t1024 4
- static is_resource(potential_resource)[source]
Check if the input value (
strorint) follows validResource.amountsyntax
- property resource
The type of this resource
- property unit
The unit of this resource
- property amount
The original amount of this resource
- class sane.resources.AcquirableResource[source]
Bases:
ResourceA
Resourcethat also tracks the amount acquired internallyThis class internally contains another
Resourcethat tracks the acquirable amount of the resouce. The original acquirable amount always matches theamountset at instantiation, and settingamountafterwards results in undefined behavior.All supported binary operations on an
AcquirableResourcereturn a newAcquirableResourceand operate on the underlyingacquirableamount. TheAcquirableResource.amountis unaffected.For example:
res_a = sane.resource.Resource( "mem", "4gb" ) res_b = sane.resource.Resource( "mem", "1gb" ) res_c = res_a - res_b res_c.current_str # outputs "3gb" res_c.total_str # outputs the original "4gb"
- __init__(resource, amount)[source]
Create a
Resourcewith typeresource- Parameters:
resource – Set the type of the resource. Resources of different types cannot interoperate.
amount – Set the
amountthat this resource is. See class summary for valid syntax.unit – If set, overrides the detected unit (if any) passed in via
amount
- property current
The current
acquirableamount- Parameters:
amount – If set, changes the
acquirable.amountto this value.
- property used
The total used amount of resources,
total-acquirable.total
- class sane.resources.ResourceRequestor[source]
Bases:
OptionLoaderAggregates any arbitrary resource requests to be made to a
ResourceProviderNote
Resources listed here are stored verbatim and thus can be anything. The onus of allocation of resources is left to the
ResourceProviderimplementation. The default classes only support resources that would match theResourcesyntax.User Interface
User Methods
- add_resource_requirements(resource_dict)[source]
Add resource requirements to this requestor
Hint
See
Resourcefor syntax on default supported valuesAdd an arbitrary dict of key-value pairs to this requestor. The key-value pairs in this dict will eventually be requested from a
ResourceRequestorfor:If the value in a key-value pair is of type
dict, it will be considered an override resource request specific to the name of the key. This overridedictwill be kept separately in an internal location to be used later. Multiple nesteddictoverrides are not allowed.See
resources()for more info.As an example:
{ "cpus" : 12, "mem" : "1gb", "slots" : 1 "specific_provider" : { "cpus" : 36, "mem" : "3gb" } }
The values of
"specific_provider"will only be used (in addition to any unmodified values in the top-level dict) if thecurrent_hostmatches this key.Note
While the
resource_dictcan be arbitrary values, it is on theResourceProvider(i.e.sane.Host) to be able to provide these resources.Notably, any resources that do not follow the
Resourcesyntax are left strictly to the provider class implementation. The default classes do not support values outside ofResourceunless specified.- Parameters:
resource_dict (dict)
User Attributes & Properties
- resources(override=None)[source]
Return a copy of the current resources requested
During workflow execution, the
current_hostwill be provided as theoverridevalue when requesting resources from thesane.Hostviaresources.ResourceProvider.acquire_resources()
- local
Control if the resources requested should be provided from a local pool if a
NonLocalProvideris used. If set toNonethen resource delegation is left to the provider,Trueto force local, andFalseto force non-local. If the provider is a normalResourceProviderthis option has no effect.
Internal API
- load_core_options(options, origin)[source]
From
OptionLoader.load_core_options():Any processed field should be removed from the options dict, with everything else ignored. All listed options are cummulative and optional unless specified otherwise.
See
load_options()for parameters.From
ResourceRequestor.load_core_options():Load
ResourceRequestorresource requirementsThe following key is loaded verbatim into
add_resource_requirements():"resources"
The following key is loaded if possible, defaulting to
None:"local"=>local
- class sane.resources.ResourceProvider[source]
Bases:
OptionLoaderManages and provides use of
AcquirableResourcesDuring workflow execution the
ResourceProviderwill be given theresourcesof each runnableResourceRequestor(Action) to check for availability, acquire, and finally release theresourcesat completion.User Interface
User Methods
- add_resources(resource_dict, override=False)[source]
Add resources to this provider that can be acquired
Hint
See
Resourcefor syntax on default supported valuesAdd a dict of key-value pairs to this provider. The key-value pairs in this dict will be used to create
AcquirableResourceinstances that track resource requests from aResourceRequestor.An example options
dict{ "cpus" : 12, "mem" : "1gb", "slots" : 2 }
The above
resource_dictwould provide 12 counts of"cpus", 1024 3bunits of"mem", and 2 counts of"slots".Important
The
ResourceProviderhas no inherent understanding of the units, amounts, or names of resources. Internally, resources will be tracked but at acquisition these resources will not correspond to any form of real hardware / software allocations or locks unless logic within a custom implementation of a derivedResourceProviderspecifies.- Parameters:
resource_dict (dict)
User Attributes & Properties
- property resources: Dict[str, AcquirableResource]
A copy of the available resources
- Returns:
a deep copy of the internal resources in their current state
- Return type:
Internal API
- load_core_options(options, origin)[source]
From
OptionLoader.load_core_options:Any processed field should be removed from the options dict, with everything else ignored. All listed options are cummulative and optional unless specified otherwise.
See
load_options()for parameters.From
ResourceProvider.load_core_options():Load the available resources for this
ResourceProviderThe following key is loaded verbatim into
add_resources()and thus should use the sameamountsyntax:"resources"
The following key is loaded into the internal
_mapperas adict[str,list[str]]viaadd_mapping(), where each key in thedictis a resource name/type and the value is a list of strings to use as aliases:"mapping"
An example options
dict{ "resources" : { "cpus" : 123, "mem" : "64mb", } "mapping" : { "ncpus" : [ "cpus", "cpu", "procs", "proc", "processors" ] } }
The above options would provide map
"cpus"to"ncpus"and add anAcquirableResourceof type"ncpus"with amount 123 and anAcquirableResourceof type"mem"with amount 64mb to theresources.Note
When using a mapping, the
ResourceRequestorandResourceProvidercan use any of the alias names or map key itself in itsresources. Within theResourceProvider, allresourceswill always be internally mapped to the corresponding map key if available.This allows the creation of
ResourceRequestorandResourceProviderthat for one reason or another wish to refer to the same resources by different names.
- resources_available(resource_dict, requestor, log=True)[source]
Check if the all resources in the requested
resource_dictare currently available- Parameters:
resource_dict (dict)
requestor (ResourceRequestor)
- Return type:
- acquire_resources(resource_dict, requestor)[source]
Acquire all the resources in the
resource_dict- Parameters:
resource_dict (dict)
requestor (ResourceRequestor)
- release_resources(resource_dict, requestor)[source]
Release all the resources in the
resources_dict- Parameters:
resource_dict (dict)
requestor (ResourceRequestor)
- class sane.resources.NonLocalProvider[source]
Bases:
ResourceProviderAn abstract base class specialization of
ResourceProviderThis class introduces the concept of a “local” pool of resources separate from the rest of the
resourcesthis provider offers. This nomenclature suggests that allresourcesdirectly in this class (not in thelocal_resources) are thus nonlocal.The internal local pool is itself a
ResourceProvider. The local pool and this instance share a commonResourceMapper.User Interface
User Attributes & Properties
- local_resources
An internal
ResourceProviderto manage local resource requests
- default_local
Set whether
ResourceRequestorwithlocalset toNoneshould default to usinglocal_resources
- force_local
Set to force all
ResourceRequestorto acquire fromlocal_resources, regardless oflocalsetting
Internal API
- load_core_options(options, origin)[source]
From
OptionLoader.load_core_options:Any processed field should be removed from the options dict, with everything else ignored. All listed options are cummulative and optional unless specified otherwise.
See
load_options()for parameters.From
NonLocalProvider.load_core_options():Load local resources into
local_resourcesand control flagsThe following key is loaded verbatim into
local_resourcesviaadd_resources():"local_resources"
The following keys are loaded, if available, into their respective attribute. If not present, the attributes are unmodified:
"default_local"=>default_local"force_local"=>force_local
An example options
dict{ "local_resources" : { "cpus" : 4, "mem" : "2gb" }, "default_local" : True }
From
ResourceProvider.load_core_options():Load the available resources for this
ResourceProviderThe following key is loaded verbatim into
add_resources()and thus should use the sameamountsyntax:"resources"
The following key is loaded into the internal
_mapperas adict[str,list[str]]viaadd_mapping(), where each key in thedictis a resource name/type and the value is a list of strings to use as aliases:"mapping"
An example options
dict{ "resources" : { "cpus" : 123, "mem" : "64mb", } "mapping" : { "ncpus" : [ "cpus", "cpu", "procs", "proc", "processors" ] } }
The above options would provide map
"cpus"to"ncpus"and add anAcquirableResourceof type"ncpus"with amount 123 and anAcquirableResourceof type"mem"with amount 64mb to theresources.Note
When using a mapping, the
ResourceRequestorandResourceProvidercan use any of the alias names or map key itself in itsresources. Within theResourceProvider, allresourceswill always be internally mapped to the corresponding map key if available.This allows the creation of
ResourceRequestorandResourceProviderthat for one reason or another wish to refer to the same resources by different names.
Customizable Functions
The
NonLocalProviderclass is by design an abstract base class to force a specialized implementation to be defined. This class has no inherent knowledge abount how nonlocal resources would be requested or managed.- abstractmethod nonlocal_resources_available(resource_dict, requestor, log=True)[source]
Tell us how to determine if nonlocal resources are available
- Parameters:
requestor (ResourceRequestor)
- abstractmethod nonlocal_acquire_resources(resource_dict, requestor)[source]
Tell us how to acquire nonlocal resources
- Parameters:
requestor (ResourceRequestor)
- abstractmethod nonlocal_release_resources(resource_dict, requestor)[source]
Tell us how to release nonlocal resources
- Parameters:
requestor (ResourceRequestor)