Пример #1
0
    def generate_context(wkchain_cls, inputs, outline_steps):
        """instantiate a WorkChain,
        call a list of methods (that should be part of `spec.outline`),
        then return a sanitized version of the workchain context for testing
        """
        from aiida.common.extendeddicts import AttributeDict
        from aiida.engine import ProcessBuilder
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager
        from aiida.orm import Node

        class ContextDumper(yaml.Dumper):
            """Custom yaml dumper for a process context."""
            def represent_data(self, data):
                if isinstance(data, Node):
                    data = str(data.__class__)
                if isinstance(data, AttributeDict):
                    data = dict(data)

                return super(ContextDumper, self).represent_data(data)

        manager = get_manager()
        runner = manager.get_runner()

        if isinstance(inputs, ProcessBuilder):
            wkchain = instantiate_process(runner, inputs)
        else:
            wkchain = instantiate_process(runner, wkchain_cls, **inputs)
        step_outcomes = []
        for step in outline_steps:
            step_outcomes.append(getattr(wkchain, step)())

        context = yaml.dump(wkchain.ctx, Dumper=ContextDumper)
        return wkchain, step_outcomes, yaml.safe_load(context)
Пример #2
0
    def generate_calcinfo(entry_point_name, folder, inputs=None):
        """Generate a `CalcInfo` instance for testing calculation jobs.

        A new `CalcJob` process instance is instantiated,
        and `prepare_for_submission` is called to populate the supplied folder,
        with raw inputs.

        Parameters
        ----------
        entry_point_name: str
        folder: aiida.common.folders.Folder
        inputs: dict or None

        """
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager
        from aiida.plugins import CalculationFactory

        manager = get_manager()
        runner = manager.get_runner()

        process_class = CalculationFactory(entry_point_name)
        process = instantiate_process(runner, process_class, **inputs)

        calc_info = process.prepare_for_submission(folder)

        return calc_info
Пример #3
0
    def inner(inputs=None, settings=None):

        if inputs is None:
            inputs = vasp_inputs(settings)
        manager = get_manager()
        runner = manager.get_runner()

        return instantiate_process(runner, VaspCalculation, **inputs)
Пример #4
0
def immigrate_existing(builder, remote_data, seal=True):
    """Immigrate a Calculation that was not run using AiiDa.

    :param builder: a populated builder instance for a CalcJob
    :type builder: aiida.engine.processes.builder.ProcessBuilder
    :param remote_data: a remote data folder,
        containing the output files required for parsing
    :type remote_data: aiida.orm.RemoteData
    :param seal: whether to seal the calc node, from further attribute changes
    :type seal: bool

    :rtype: aiida.orm.CalcJobNode

    """
    # initialise calcjob
    runner = get_manager().get_runner()
    pw_calc_cls = builder._process_class
    process = instantiate_process(runner, pw_calc_cls, **builder)
    calc_node = process.node

    # prepare for submission
    with SandboxFolder() as temp_folder:
        calc_info = process.presubmit(temp_folder)  # noqa F841
        calc_node.put_object_from_tree(temp_folder.abspath, force=True)

    # link remote folder to calc_node
    if not remote_data.is_stored:
        remote_data.store()
    remote_data.add_incoming(
        calc_node, link_type=LinkType.CREATE, link_label="remote_folder"
    )
    calc_node.set_remote_workdir(remote_data.get_remote_path())
    transport = remote_data.computer.get_transport()

    with SandboxFolder() as temp_retrieved:
        # retrieved output files
        retrieve_calculation(calc_node, transport, temp_retrieved.abspath)
        # parse output
        calc_node.set_state(CalcJobState.PARSING)
        exit_code = process.parse(temp_retrieved.abspath)
    # link outgoing nodes
    process.update_outputs()

    # finalise calc node
    calc_node.delete_state()
    calc_node.delete_checkpoint()
    calc_node.set_process_state(ProcessState.FINISHED)
    calc_node.set_exit_status(exit_code.status)
    calc_node.set_exit_message(exit_code.message)
    if seal:
        calc_node.seal()

    # record that the node was created via immigration
    calc_node.set_extra("immigrated", True)
    calc_node.set_extra("immigration_func", __name__)

    return calc_node
Пример #5
0
def test_generate_base_calc(base_calc):
    """Test that it is possible to start the generatione of an instance of the base calculation class."""

    from aiida_vasp.calcs.base import VaspCalcBase

    manager = get_manager()
    runner = manager.get_runner()
    inputs = AttributeDict()

    metadata = AttributeDict({
        'options': {
            'resources': {
                'num_machines': 1,
                'num_mpiprocs_per_machine': 1
            }
        }
    })
    inputs.metadata = metadata

    # Need more input, so we will get an ValueError because we do not pass code
    with pytest.raises(ValueError):
        instantiate_process(runner, VaspCalcBase, **inputs)
Пример #6
0
    def _generate_calc_job(entry_point_name, inputs=None):
        """Fixture to generate a mock `CalcInfo` for testing calculation jobs."""
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager
        from aiida.plugins import CalculationFactory

        manager = get_manager()
        runner = manager.get_runner()

        process_class = CalculationFactory(entry_point_name)
        process = instantiate_process(runner, process_class, **inputs)

        return process
Пример #7
0
    def _generate_calc_job(folder, builder):
        """Fixture to generate a mock `CalcInfo` for testing calculation jobs."""
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager

        manager = get_manager()
        runner = manager.get_runner()

        process_class = builder._process_class  # pylint: disable=protected-access
        process = instantiate_process(runner, process_class, **dict(builder))

        calc_info = process.prepare_for_submission(folder)

        return calc_info
Пример #8
0
    def _generate_workchain(entry_point, inputs):
        """Generate an instance of a `WorkChain` with the given entry point and inputs.
        :param entry_point: entry point name of the work chain subclass.
        :param inputs: inputs to be passed to process construction.
        :return: a `WorkChain` instance.
        """
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager
        from aiida.plugins import WorkflowFactory

        process_class = WorkflowFactory(entry_point)
        runner = get_manager().get_runner()
        process = instantiate_process(runner, process_class, **inputs)

        return process
Пример #9
0
    def test_exposed_outputs(self):
        """Test the ``Process.exposed_outputs`` method."""
        from aiida.common import AttributeDict
        from aiida.common.links import LinkType
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager

        runner = get_manager().get_runner()

        class ChildProcess(Process):
            """Dummy process with normal output and output namespace."""

            _node_class = orm.WorkflowNode

            @classmethod
            def define(cls, spec):
                super(ChildProcess, cls).define(spec)
                spec.input('input', valid_type=orm.Int)
                spec.output('output', valid_type=orm.Int)
                spec.output('name.space', valid_type=orm.Int)

        class ParentProcess(Process):
            """Dummy process that exposes the outputs of ``ChildProcess``."""

            _node_class = orm.WorkflowNode

            @classmethod
            def define(cls, spec):
                super(ParentProcess, cls).define(spec)
                spec.input('input', valid_type=orm.Int)
                spec.expose_outputs(ChildProcess)

        node_child = orm.WorkflowNode().store()
        node_output = orm.Int(1).store()
        node_output.add_incoming(node_child, link_label='output', link_type=LinkType.RETURN)
        node_name_space = orm.Int(1).store()
        node_name_space.add_incoming(node_child, link_label='name__space', link_type=LinkType.RETURN)

        process = instantiate_process(runner, ParentProcess, input=orm.Int(1))
        exposed_outputs = process.exposed_outputs(node_child, ChildProcess)

        expected = AttributeDict({
            'name': {
                'space': node_name_space,
            },
            'output': node_output,
        })
        self.assertEqual(exposed_outputs, expected)
Пример #10
0
    def instantiate_process(self, state=CalcJobState.PARSING):
        """Instantiate a process with default inputs and return the `Process` instance."""
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager

        inputs = deepcopy(self.inputs)
        inputs['code'] = self.remote_code

        manager = get_manager()
        runner = manager.get_runner()

        process_class = CalculationFactory('arithmetic.add')
        process = instantiate_process(runner, process_class, **inputs)
        process.node.set_state(state)

        return process
Пример #11
0
    def _generate_calc_job(folder, entry_point_name, inputs=None, return_process=False):
        """Fixture to generate a mock `CalcInfo` for testing calculation jobs."""
        from aiida.engine.utils import instantiate_process
        from aiida.manage.manager import get_manager
        from aiida.plugins import CalculationFactory

        inputs = inputs or {}
        manager = get_manager()
        runner = manager.get_runner()

        process_class = CalculationFactory(entry_point_name)
        process = instantiate_process(runner, process_class, **inputs)

        if return_process:
            return process

        return process.prepare_for_submission(folder)
Пример #12
0
def base_calc(fresh_aiida_env, vasp_code):
    """An instance of a VaspCalcBase Process."""
    from aiida_vasp.calcs.base import VaspCalcBase
    manager = get_manager()
    runner = manager.get_runner()
    inputs = AttributeDict()

    metadata = AttributeDict({
        'options': {
            'resources': {
                'num_machines': 1,
                'num_mpiprocs_per_machine': 1
            }
        }
    })

    inputs.code = vasp_code
    inputs.metadata = metadata

    return instantiate_process(runner, VaspCalcBase, **inputs)
Пример #13
0
def process(aiida_local_code_factory):
    """Instantiate a process with default inputs and return the `Process` instance."""
    from aiida.engine.utils import instantiate_process
    from aiida.manage.manager import get_manager

    inputs = {
        'code': aiida_local_code_factory('arithmetic.add', '/bin/bash'),
        'x': orm.Int(1),
        'y': orm.Int(2),
        'metadata': {
            'options': {}
        }
    }

    manager = get_manager()
    runner = manager.get_runner()

    process_class = CalculationFactory('arithmetic.add')
    process = instantiate_process(runner, process_class, **inputs)
    process.node.set_state(CalcJobState.PARSING)

    return process
Пример #14
0
    def _generate_process(inputs=None):

        base_inputs = {
            'code': aiida_local_code_factory('arithmetic.add', '/bin/bash'),
            'x': orm.Int(1),
            'y': orm.Int(2),
            'metadata': {
                'options': {}
            }
        }

        if inputs is not None:
            base_inputs = {**base_inputs, **inputs}

        manager = get_manager()
        runner = manager.get_runner()

        process_class = CalculationFactory('arithmetic.add')
        process = instantiate_process(runner, process_class, **base_inputs)
        process.node.set_state(CalcJobState.PARSING)

        return process
Пример #15
0
def instantiate_process_builder(builder):
    """Instantiate a process, from a `ProcessBuilder`."""
    manager = get_manager()
    runner = manager.get_runner()
    return instantiate_process(runner, builder)
Пример #16
0
def instantiate_process_cls(process_cls, inputs):
    """Instantiate a process, from its class and inputs."""
    manager = get_manager()
    runner = manager.get_runner()
    return instantiate_process(runner, process_cls, **inputs)
Пример #17
0
def test_gaussian(fixture_code):

    geometry_file = os.path.join(tests.TEST_DIR, "data", 'ch4.xyz')
    expected_inp_file = os.path.join(tests.TEST_DIR, "data",
                                     'gaussian_test.inp')

    # structure
    structure = StructureData(
        pymatgen_molecule=Molecule.from_file(geometry_file))

    num_cores = 1
    memory_mb = 1000

    # Main parameters: geometry optimization
    parameters = {
        'link0_parameters': {
            '%chk': 'aiida.chk',
            '%mem': "%dMB" % memory_mb,
            '%nprocshared': str(num_cores),
        },
        'functional': 'BLYP',
        'basis_set': '6-31g',
        'charge': 0,
        'multiplicity': 1,
        'route_parameters': {
            'scf': {
                'maxcycle': 512,
                'cdiis': None
            },
            'nosymm': None,
            'opt': None,
        },
    }

    # Build the inputs dictionary with a "fake" executable

    inputs = {
        'code': fixture_code('gaussian'),  #load_code("gaussian09@localhost"),
        'structure': structure,
        'parameters': Dict(dict=parameters),
        'metadata': {
            'options': {
                'resources': {
                    'num_machines': 1,
                    'tot_num_mpiprocs': 1,
                },
                'max_wallclock_seconds': 1800,
                'withmpi': False
            }
        }
    }

    # Prepare the fake calculation for submission in a "sandbox folder"

    from aiida.engine.utils import instantiate_process
    from aiida.manage.manager import get_manager
    from aiida.common.folders import SandboxFolder

    manager = get_manager()
    runner = manager.get_runner()

    process_class = CalculationFactory('gaussian')
    process = instantiate_process(runner, process_class, **inputs)

    sandbox_folder = SandboxFolder()

    calc_info = process.prepare_for_submission(sandbox_folder)

    with sandbox_folder.open('aiida.inp') as handle:
        input_written = handle.read()

    with open(expected_inp_file, 'r') as f:
        expected_inp = f.read()

    assert (input_written == expected_inp)