aiida-pythonjob 0.4.0__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {aiida_pythonjob-0.4.0/src/aiida_pythonjob.egg-info → aiida_pythonjob-0.4.2}/PKG-INFO +2 -2
  2. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/pyproject.toml +1 -1
  3. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/__init__.py +1 -1
  4. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/calculations/pythonjob.py +11 -1
  5. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/calculations/utils.py +31 -3
  6. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/parsers/pythonjob.py +1 -0
  7. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/utils.py +4 -1
  8. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2/src/aiida_pythonjob.egg-info}/PKG-INFO +2 -2
  9. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob.egg-info/requires.txt +1 -1
  10. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/LICENSE +0 -0
  11. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/README.md +0 -0
  12. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/setup.cfg +0 -0
  13. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/calculations/__init__.py +0 -0
  14. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/calculations/common.py +0 -0
  15. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/calculations/pyfunction.py +0 -0
  16. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/config.py +0 -0
  17. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/__init__.py +0 -0
  18. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/atoms.py +0 -0
  19. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/common_data.py +0 -0
  20. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/deserializer.py +0 -0
  21. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/jsonable_data.py +0 -0
  22. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/pickled_data.py +0 -0
  23. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/serializer.py +0 -0
  24. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/data/utils.py +0 -0
  25. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/decorator.py +0 -0
  26. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/launch.py +0 -0
  27. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/parsers/__init__.py +0 -0
  28. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob/parsers/utils.py +0 -0
  29. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob.egg-info/SOURCES.txt +0 -0
  30. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob.egg-info/dependency_links.txt +0 -0
  31. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob.egg-info/entry_points.txt +0 -0
  32. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/src/aiida_pythonjob.egg-info/top_level.txt +0 -0
  33. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_create_env.py +0 -0
  34. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_data.py +0 -0
  35. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_entry_points.py +0 -0
  36. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_jsonable_data.py +0 -0
  37. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_parser.py +0 -0
  38. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_pickled_data.py +0 -0
  39. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_pyfunction.py +0 -0
  40. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_pythonjob.py +0 -0
  41. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_serializer.py +0 -0
  42. {aiida_pythonjob-0.4.0 → aiida_pythonjob-0.4.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiida-pythonjob
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Run Python functions on a remote computer.
5
5
  Author-email: Xing Wang <xingwang1991@gmail.com>
6
6
  License: MIT License
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
38
38
  License-File: LICENSE
39
39
  Requires-Dist: aiida-core<3,>=2.3
40
40
  Requires-Dist: ase
41
- Requires-Dist: node-graph>=0.3.0
41
+ Requires-Dist: node-graph>=0.3.9
42
42
  Provides-Extra: test
43
43
  Requires-Dist: pgtest>=1.3.1,~=1.3; extra == "test"
44
44
  Requires-Dist: coverage~=7.0; extra == "test"
@@ -22,7 +22,7 @@ requires-python = ">=3.9"
22
22
  dependencies = [
23
23
  "aiida-core>=2.3,<3",
24
24
  "ase",
25
- "node-graph>=0.3.0",
25
+ "node-graph>=0.3.9",
26
26
  ]
27
27
 
28
28
  [project.optional-dependencies]
@@ -1,6 +1,6 @@
1
1
  """AiiDA plugin that run Python function on remote computers."""
2
2
 
3
- __version__ = "0.4.0"
3
+ __version__ = "0.4.2"
4
4
 
5
5
  from node_graph import socket_spec as spec
6
6
 
@@ -143,6 +143,12 @@ class PythonJob(FunctionProcessMixin, CalcJob):
143
143
  invalidates_cache=True,
144
144
  message="The script failed for an unknown reason.\n{exception}\n{traceback}",
145
145
  )
146
+ spec.exit_code(
147
+ 329,
148
+ "ERROR_IMPORT_MPI4PY_FAILED",
149
+ invalidates_cache=True,
150
+ message="Trying to run with MPI support, but importing mpi4py failed.\n{exception}\n{traceback}",
151
+ )
146
152
 
147
153
  @override
148
154
  def _setup_db_record(self) -> None:
@@ -242,6 +248,7 @@ class PythonJob(FunctionProcessMixin, CalcJob):
242
248
  pickled_function=pickled_function,
243
249
  source_code=source_code,
244
250
  function_name=function_name,
251
+ withmpi=self.inputs.metadata.options.get("withmpi", False),
245
252
  )
246
253
 
247
254
  # Write the script
@@ -283,7 +290,10 @@ class PythonJob(FunctionProcessMixin, CalcJob):
283
290
  local_copy_list.append((file_data.uuid, file_data.filename, filename))
284
291
 
285
292
  codeinfo = CodeInfo()
286
- codeinfo.stdin_name = self.options.input_filename
293
+ if self.options.get("withmpi", False):
294
+ codeinfo.cmdline_params = [self.options.input_filename]
295
+ else:
296
+ codeinfo.stdin_name = self.options.input_filename
287
297
  codeinfo.stdout_name = self.options.output_filename
288
298
  codeinfo.code_uuid = self.inputs.code.uuid
289
299
 
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
 
4
4
  def generate_script_py(
5
- pickled_function: bytes | None, source_code: str | None, function_name: str = "user_function"
5
+ pickled_function: bytes | None, source_code: str | None, function_name: str = "user_function", withmpi: bool = False
6
6
  ) -> str:
7
7
  """
8
8
  Generate the script.py content as a single string with robust exception handling.
@@ -36,6 +36,23 @@ def generate_script_py(
36
36
  " write_error_file('IMPORT_CLOUDPICKLE_FAILED', e, traceback.format_exc())",
37
37
  " sys.exit(1)",
38
38
  "",
39
+ ]
40
+
41
+ if withmpi:
42
+ script_lines += [
43
+ " # Attempt to import mpi4py",
44
+ " try:",
45
+ " from mpi4py import MPI",
46
+ " except ImportError as e:",
47
+ " write_error_file('IMPORT_MPI4PY_FAILED', e, traceback.format_exc())",
48
+ " sys.exit(1)",
49
+ "",
50
+ " # MPI initialization",
51
+ " RANK = MPI.COMM_WORLD.Get_rank()",
52
+ "",
53
+ ]
54
+
55
+ script_lines += [
39
56
  " # 2) Attempt to unpickle the inputs",
40
57
  " try:",
41
58
  " with open('inputs.pickle', 'rb') as handle:",
@@ -87,8 +104,19 @@ def generate_script_py(
87
104
  "",
88
105
  " # 5) Attempt to pickle the result",
89
106
  " try:",
90
- " with open('results.pickle', 'wb') as handle:",
91
- " pickle.dump(result, handle)",
107
+ ]
108
+ if withmpi:
109
+ script_lines += [
110
+ " if RANK == 0:", # Only the root process saves the result
111
+ " with open('results.pickle', 'wb') as handle:",
112
+ " pickle.dump(result, handle)",
113
+ ]
114
+ else:
115
+ script_lines += [
116
+ " with open('results.pickle', 'wb') as handle:",
117
+ " pickle.dump(result, handle)",
118
+ ]
119
+ script_lines += [
92
120
  " except Exception as e:",
93
121
  " write_error_file('PICKLE_RESULTS_FAILED', e, traceback.format_exc())",
94
122
  " sys.exit(1)",
@@ -10,6 +10,7 @@ from .utils import parse_outputs
10
10
  # Map error_type from script.py to exit code label
11
11
  ERROR_TYPE_TO_EXIT_CODE = {
12
12
  "IMPORT_CLOUDPICKLE_FAILED": "ERROR_IMPORT_CLOUDPICKLE_FAILED",
13
+ "IMPORT_MPI4PY_FAILED": "ERROR_IMPORT_MPI4PY_FAILED",
13
14
  "UNPICKLE_INPUTS_FAILED": "ERROR_UNPICKLE_INPUTS_FAILED",
14
15
  "UNPICKLE_FUNCTION_FAILED": "ERROR_UNPICKLE_FUNCTION_FAILED",
15
16
  "FUNCTION_EXECUTION_FAILED": "ERROR_FUNCTION_EXECUTION_FAILED",
@@ -307,7 +307,10 @@ def serialize_ports(
307
307
  for key, value in python_data.items():
308
308
  if key in fields:
309
309
  child_spec = fields[key]
310
- if child_spec.is_namespace():
310
+ # Metadata is not serialized
311
+ if child_spec.meta.is_metadata:
312
+ out[key] = value
313
+ elif child_spec.is_namespace():
311
314
  out[key] = serialize_ports(value, child_spec, serializers=serializers)
312
315
  else:
313
316
  out[key] = general_serializer(value, serializers=serializers, store=False)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiida-pythonjob
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Run Python functions on a remote computer.
5
5
  Author-email: Xing Wang <xingwang1991@gmail.com>
6
6
  License: MIT License
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
38
38
  License-File: LICENSE
39
39
  Requires-Dist: aiida-core<3,>=2.3
40
40
  Requires-Dist: ase
41
- Requires-Dist: node-graph>=0.3.0
41
+ Requires-Dist: node-graph>=0.3.9
42
42
  Provides-Extra: test
43
43
  Requires-Dist: pgtest>=1.3.1,~=1.3; extra == "test"
44
44
  Requires-Dist: coverage~=7.0; extra == "test"
@@ -1,6 +1,6 @@
1
1
  aiida-core<3,>=2.3
2
2
  ase
3
- node-graph>=0.3.0
3
+ node-graph>=0.3.9
4
4
 
5
5
  [docs]
6
6
  sphinx_rtd_theme
File without changes