Skip to content

Commit

Permalink
Get rid of vestigial leading underscores for non-storable inputs
Browse files Browse the repository at this point in the history
The old convention to mark Process inputs as non database storable
was to name them with a leading underscore. Now there is a proper
mixin WithNonDb that is mixed into the InputPort and PortNamespace
classes, which adds the attribute non_db, which can be used to
mark a port as storable or non storable. We remove the underscores
from the predefined Process and Workchain inputs

	* _options
	* _label
	* _description
	* _store_provenance

Workchain implementations and JobProcess submissions by users will
have to be updated to remove these leading underscored from the
input dictionaries as well
  • Loading branch information
sphuber committed Feb 5, 2018
1 parent ba9f9fa commit bf09099
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 51 deletions.
18 changes: 9 additions & 9 deletions aiida/backends/tests/work/job_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ def test_job_process_set_label_and_description(self):
label = 'test_label'
description = 'test_description'
inputs = {
'_options': {
'options': {
'computer': self.computer,
'resources': {
'num_machines': 1,
'num_mpiprocs_per_machine': 1
},
'max_wallclock_seconds': 10,
},
'_label': label,
'_description': description
'label': label,
'description': description
}
process = TemplatereplacerCalculation.process()
job = process(inputs)
Expand All @@ -98,16 +98,16 @@ def test_job_process_set_none(self):
Verify that calculation label and description can be set to ``None``.
"""
inputs = {
'_options': {
'options': {
'computer': self.computer,
'resources': {
'num_machines': 1,
'num_mpiprocs_per_machine': 1
},
'max_wallclock_seconds': 10,
},
'_label': None,
'_description': None
'label': None,
'description': None
}

process = TemplatereplacerCalculation.process()
Expand Down Expand Up @@ -138,7 +138,7 @@ def test_job_process_with_additional_parameter(self):
label = 'test_label'
description = 'test_description'
inputs = {
'_options': {
'options': {
'computer': self.computer,
'resources': {
'num_machines': 1,
Expand All @@ -150,8 +150,8 @@ def test_job_process_with_additional_parameter(self):
'a': Int(1),
'b': Int(2),
},
'_label': label,
'_description': description
'label': label,
'description': description
}
process = AdditionalParameterCalculation.process()
job = process(inputs)
10 changes: 5 additions & 5 deletions aiida/backends/tests/work/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_input_link_creation(self):
dummy_inputs = ["1", "2", "3", "4"]

inputs = {l: Int(l) for l in dummy_inputs}
inputs['_store_provenance'] = True
inputs['store_provenance'] = True
p = test_utils.DummyProcess(inputs)

for label, value in p._calc.get_inputs_dict().iteritems():
Expand All @@ -119,18 +119,18 @@ def test_seal(self):
self.assertTrue(load_node(pk=pid).is_sealed)

def test_description(self):
dp = test_utils.DummyProcess(inputs={'_description': "Rockin' process"})
dp = test_utils.DummyProcess(inputs={'description': "Rockin' process"})
self.assertEquals(dp.calc.description, "Rockin' process")

with self.assertRaises(ValueError):
test_utils.DummyProcess(inputs={'_description': 5})
test_utils.DummyProcess(inputs={'description': 5})

def test_label(self):
dp = test_utils.DummyProcess(inputs={'_label': 'My label'})
dp = test_utils.DummyProcess(inputs={'label': 'My label'})
self.assertEquals(dp.calc.label, 'My label')

with self.assertRaises(ValueError):
test_utils.DummyProcess(inputs={'_label': 5})
test_utils.DummyProcess(inputs={'label': 5})

def test_work_calc_finish(self):
p = test_utils.DummyProcess()
Expand Down
62 changes: 33 additions & 29 deletions aiida/work/job_processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
###########################################################################
from functools import partial
import plum
import plum.port as port
from voluptuous import Any

from plum.port import PortNamespace
from aiida.backends.utils import get_authinfo
from aiida.common.datastructures import calc_states
from aiida.common.lang import override
Expand Down Expand Up @@ -77,7 +76,7 @@ def _do_transport_operation(self, operation, authinfo, transport):
class JobProcess(processes.Process):
TRANSPORT_OPERATION = 'TRANSPORT_OPERATION'
CALC_NODE_LABEL = 'calc_node'
OPTIONS_INPUT_LABEL = '_options'
OPTIONS_INPUT_LABEL = 'options'
_CALC_CLASS = None

# Class defaults
Expand All @@ -94,21 +93,21 @@ def define(cls_, spec):

# Calculation options
options = {
"max_wallclock_seconds": int,
"resources": dict,
"custom_scheduler_commands": unicode,
"queue_name": basestring,
"computer": Computer,
"withmpi": bool,
"mpirun_extra_params": Any(list, tuple),
"import_sys_environment": bool,
"environment_variables": dict,
"priority": unicode,
"max_memory_kb": int,
"prepend_text": unicode,
"append_text": unicode,
'max_wallclock_seconds': int,
'resources': dict,
'custom_scheduler_commands': unicode,
'queue_name': basestring,
'computer': Computer,
'withmpi': bool,
'mpirun_extra_params': Any(list, tuple),
'import_sys_environment': bool,
'environment_variables': dict,
'priority': unicode,
'max_memory_kb': int,
'prepend_text': unicode,
'append_text': unicode,
}
spec.input(cls.OPTIONS_INPUT_LABEL, validator=processes.DictSchema(options))
spec.input(cls.OPTIONS_INPUT_LABEL, validator=processes.DictSchema(options), non_db=True)

# Inputs from use methods
for key, use_method in calc_class._use_methods.iteritems():
Expand All @@ -128,11 +127,13 @@ def define(cls_, spec):
class_name = "{}_{}".format(cls.__name__, utils.class_name(calc_class))

# Dynamically create the type for this Process
return type(class_name, (cls,),
{
plum.process.Process.define.__name__: classmethod(define),
'_CALC_CLASS': calc_class
})
return type(
class_name, (cls,),
{
plum.process.Process.define.__name__: classmethod(define),
'_CALC_CLASS': calc_class
}
)

@classmethod
def get_state_classes(cls):
Expand Down Expand Up @@ -162,18 +163,21 @@ def _setup_db_record(self):
# Set all the attributes using the setter methods
for name, value in self.inputs.get(self.OPTIONS_INPUT_LABEL, {}).iteritems():
if value is not None:
getattr(self._calc, "set_{}".format(name))(value)
getattr(self._calc, 'set_{}'.format(name))(value)

# Use the use_[x] methods to join up the links in this case
for name, input in self.get_provenance_inputs_iterator():
if input is None or name is self.OPTIONS_INPUT_LABEL:
for name, input_value in self.get_provenance_inputs_iterator():

port = self.spec().inputs[name]

if input_value is None or port.non_db:
continue

# Call the 'use' methods to set up the data-calc links
if isinstance(self.spec().inputs[name], port.PortNamespace):
if isinstance(port, PortNamespace):
additional = self._CALC_CLASS._use_methods[name]['additional_parameter']

for k, v in input.iteritems():
for k, v in input_value.iteritems():
try:
getattr(self._calc, 'use_{}'.format(name))(v, **{additional: k})
except AttributeError:
Expand All @@ -182,7 +186,7 @@ def _setup_db_record(self):
"the JobCalculation has no such use_{} method".format(name, name))

else:
getattr(self._calc, 'use_{}'.format(name))(input)
getattr(self._calc, 'use_{}'.format(name))(input_value)

# Get the computer from the code if necessary
if self._calc.get_computer() is None and 'code' in self.inputs:
Expand All @@ -192,7 +196,7 @@ def _setup_db_record(self):

parent_calc = self.get_parent_calc()
if parent_calc:
self._calc.add_link_from(parent_calc, "CALL", LinkType.CALL)
self._calc.add_link_from(parent_calc, 'CALL', LinkType.CALL)

self._add_description_and_label()

Expand Down
16 changes: 8 additions & 8 deletions aiida/work/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ class SaveKeys(Enum):
@classmethod
def define(cls, spec):
super(Process, cls).define(spec)
spec.input("_store_provenance", valid_type=bool, default=True, non_db=True)
spec.input("_description", valid_type=basestring, required=False, non_db=True)
spec.input("_label", valid_type=basestring, required=False, non_db=True)
spec.input('store_provenance', valid_type=bool, default=True, non_db=True)
spec.input('description', valid_type=basestring, required=False, non_db=True)
spec.input('label', valid_type=basestring, required=False, non_db=True)
spec.inputs.valid_type = (aiida.orm.Data, aiida.orm.Calculation)
spec.outputs.valid_type = (aiida.orm.Data)

Expand Down Expand Up @@ -233,7 +233,7 @@ def calc(self):
def save_instance_state(self, out_state):
super(Process, self).save_instance_state(out_state)

if self.inputs._store_provenance:
if self.inputs.store_provenance:
assert self.calc.is_stored

out_state[self.SaveKeys.PARENT_PID.value] = self._parent_pid
Expand Down Expand Up @@ -358,7 +358,7 @@ def report(self, msg, *args, **kwargs):
def _create_and_setup_db_record(self):
self._calc = self.get_or_create_db_record()
self._setup_db_record()
if self.inputs._store_provenance:
if self.inputs.store_provenance:
try:
self.calc.store_all()
except ModificationNotAllowed as exception:
Expand Down Expand Up @@ -429,7 +429,7 @@ def _setup_db_record(self):
# If the input isn't stored then assume our parent created it
if parent_calc:
input_value.add_link_from(parent_calc, "CREATE", link_type=LinkType.CREATE)
if self.inputs._store_provenance:
if self.inputs.store_provenance:
input_value.store()

self.calc.add_link_from(input_value, name)
Expand All @@ -442,10 +442,10 @@ def _setup_db_record(self):

def _add_description_and_label(self):
if self.raw_inputs:
description = self.raw_inputs.get('_description', None)
description = self.raw_inputs.get('description', None)
if description is not None:
self._calc.description = description
label = self.raw_inputs.get('_label', None)
label = self.raw_inputs.get('label', None)
if label is not None:
self._calc.label = label

Expand Down

0 comments on commit bf09099

Please sign in to comment.