@@ -139,15 +139,11 @@ def parse_cp2k_output(
139
139
return geometry
140
140
141
141
142
- # typeguarding for some reason incompatible with WQ
143
- def cp2k_singlepoint_pre (
142
+ def _prepare_input (
144
143
geometry : Geometry ,
145
144
cp2k_input_dict : dict = {},
146
145
properties : tuple = (),
147
- cp2k_command : str = "" ,
148
- stdout : str = "" ,
149
- stderr : str = "" ,
150
- parsl_resource_specification : Optional [dict ] = None ,
146
+ outputs : list = [],
151
147
):
152
148
from psiflow .reference ._cp2k import (
153
149
dict_to_str ,
@@ -160,18 +156,33 @@ def cp2k_singlepoint_pre(
160
156
if "forces" in properties :
161
157
cp2k_input_dict ["force_eval" ]["print" ] = {"FORCES" : {}}
162
158
cp2k_input_str = dict_to_str (cp2k_input_dict )
159
+ with open (outputs [0 ], 'w' ) as f :
160
+ f .write (cp2k_input_str )
161
+
162
+
163
+ prepare_input = python_app (_prepare_input , executors = ['default_threads' ])
164
+
165
+
166
+ # typeguarding for some reason incompatible with WQ
167
+ def cp2k_singlepoint_pre (
168
+ cp2k_command : str = "" ,
169
+ stdout : str = "" ,
170
+ stderr : str = "" ,
171
+ inputs : list = [],
172
+ parsl_resource_specification : Optional [dict ] = None ,
173
+ ):
174
+ tmp_command = 'mytmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t "mytmpdir")'
175
+ cd_command = "cd $mytmpdir"
176
+ cp_command = "cp {} cp2k.inp" .format (inputs [0 ].filepath )
163
177
164
- # see https://unix.stackexchange.com/questions/30091/fix-or-alternative-for-mktemp-in-os-x
165
- tmp_command = 'mytmpdir=$(mktemp -d 2>/dev/null || mktemp -d -t "mytmpdir");'
166
- cd_command = "cd $mytmpdir;"
167
- write_command = 'echo "{}" > cp2k.inp;' .format (cp2k_input_str )
168
178
command_list = [
169
179
tmp_command ,
170
180
cd_command ,
171
- write_command ,
172
- cp2k_command ,
181
+ cp_command ,
182
+ cp2k_command
173
183
]
174
- return " " .join (command_list )
184
+
185
+ return ' && ' .join (command_list )
175
186
176
187
177
188
@typeguard .typechecked
@@ -222,13 +233,26 @@ def _create_apps(self):
222
233
app_pre = bash_app (cp2k_singlepoint_pre , executors = [self .executor ])
223
234
app_post = python_app (cp2k_singlepoint_post , executors = ["default_threads" ])
224
235
225
- self .app_pre = partial (
226
- app_pre ,
227
- cp2k_input_dict = self .cp2k_input_dict ,
228
- properties = tuple (self .outputs ),
229
- cp2k_command = cp2k_command ,
230
- parsl_resource_specification = wq_resources ,
231
- )
236
+ # create wrapped pre app which first parses the input file and writes it to
237
+ # disk, then call the actual bash app with the input file as a DataFuture dependency
238
+ # This is necessary because for very large structures, the size of the cp2k input
239
+ # file is too long to pass as an argument in a command line
240
+ def wrapped_app_pre (geometry , stdout : str , stderr : str ):
241
+ future = prepare_input (
242
+ geometry ,
243
+ cp2k_input_dict = self .cp2k_input_dict ,
244
+ properties = tuple (self .outputs ),
245
+ outputs = [psiflow .context ().new_file ('cp2k_' , '.inp' )],
246
+ )
247
+ return app_pre (
248
+ cp2k_command = cp2k_command ,
249
+ stdout = stdout ,
250
+ stderr = stderr ,
251
+ inputs = [future .outputs [0 ]],
252
+ parsl_resource_specification = wq_resources ,
253
+ )
254
+
255
+ self .app_pre = wrapped_app_pre
232
256
self .app_post = partial (
233
257
app_post ,
234
258
properties = tuple (self .outputs ),
0 commit comments