@@ -48,6 +48,10 @@ def run(self):
4848 input_path = os .path .abspath (self .app .context .input_path )
4949 output_path = os .path .abspath (self .app .context .output_path )
5050
51+ # Create the output directory if it does not exist
52+ if not os .path .exists (output_path ):
53+ os .makedirs (output_path , exist_ok = True )
54+
5155 # Store old pwd
5256 old_pwd = os .getcwd ()
5357
@@ -73,76 +77,77 @@ def run(self):
7377
7478 g = self .app .graph
7579
76- for op in g .gen_worklist ():
77- op_exec_context = ExecutionContext (exec_context , op )
78-
79- # Set source input for a label if op is a root node and (<data type>, <storage type>) == (DataPath, IOType.DISK)
80- is_root = g .is_root (op )
81- if is_root :
82- input_op_info = op .op_info
83- input_labels = input_op_info .get_labels (IO .INPUT )
84- for input_label in input_labels :
85- input_data_type = input_op_info .get_data_type (IO .INPUT , input_label )
86- input_storage_type = input_op_info .get_storage_type (IO .INPUT , input_label )
87- if issubclass (input_data_type , DataPath ) and input_storage_type == IOType .DISK :
88- op_exec_context .input_context .set (DataPath (input_path , read_only = True ), input_label )
89-
90- # Set destination output for a label if op is a leaf node and (<data type>, <storage type>) == (DataPath, IOType.DISK)
91- is_leaf = g .is_leaf (op )
92- if is_leaf :
93- output_op_info = op .op_info
94- output_labels = output_op_info .get_labels (IO .OUTPUT )
95- for output_label in output_labels :
96- output_data_type = output_op_info .get_data_type (IO .OUTPUT , output_label )
97- output_storage_type = output_op_info .get_storage_type (IO .OUTPUT , output_label )
98- if issubclass (output_data_type , DataPath ) and output_storage_type == IOType .DISK :
99- op_exec_context .output_context .set (DataPath (output_path , read_only = True ), output_label )
100-
101- # Change the current working directory to the working directory of the operator
102- # op_output_folder == f"{workdir}/operators/{op.uid}/{op_exec_context.get_execution_index()}/{IO.OUTPUT}"
103- relative_output_path = Path (op_exec_context .output_context .get_group_path (IO .OUTPUT )).relative_to ("/" )
104- op_output_folder = str (Path (workdir , relative_output_path ))
105- os .makedirs (op_output_folder , exist_ok = True )
106- os .chdir (op_output_folder )
107-
108- # Execute pre_compute()
109- print (Fore .BLUE + "Going to initiate execution of operator %s" % op .__class__ .__name__ + Fore .RESET )
110- op .pre_compute ()
111-
112- # Execute compute()
113- print (
114- Fore .GREEN
115- + "Executing operator %s " % op .__class__ .__name__
116- + Fore .YELLOW
117- + "(Process ID: %s, Operator ID: %s)" % (os .getpid (), op .uid )
118- + Fore .RESET
119- )
120- op .compute (op_exec_context .input_context , op_exec_context .output_context , op_exec_context )
121-
122- # Execute post_compute()
123- print (Fore .BLUE + "Done performing execution of operator %s\n " % op .__class__ .__name__ + Fore .RESET )
124- op .post_compute ()
125-
126- # Set input to next operator
127- next_ops = g .gen_next_operators (op )
128- for next_op in next_ops :
129- io_map = g .get_io_map (op , next_op )
130- if not io_map :
131- import inspect
132-
133- raise IOMappingError (
134- f"No IO mappings found for { op .name } -> { next_op .name } in "
135- f"{ inspect .getabsfile (self .app .__class__ )} "
136- )
137-
138- next_op_exec_context = ExecutionContext (exec_context , next_op )
139- for (out_label , in_labels ) in io_map .items ():
140- output = op_exec_context .output_context .get (out_label )
141- for in_label in in_labels :
142- next_op_exec_context .input_context .set (output , in_label )
143-
144- # Restore pwd
145- os .chdir (old_pwd )
80+ try :
81+ for op in g .gen_worklist ():
82+ op_exec_context = ExecutionContext (exec_context , op )
83+
84+ # Set source input for a label if op is a root node and (<data type>,<storage type>) == (DataPath,IOType.DISK)
85+ is_root = g .is_root (op )
86+ if is_root :
87+ input_op_info = op .op_info
88+ input_labels = input_op_info .get_labels (IO .INPUT )
89+ for input_label in input_labels :
90+ input_data_type = input_op_info .get_data_type (IO .INPUT , input_label )
91+ input_storage_type = input_op_info .get_storage_type (IO .INPUT , input_label )
92+ if issubclass (input_data_type , DataPath ) and input_storage_type == IOType .DISK :
93+ op_exec_context .input_context .set (DataPath (input_path , read_only = True ), input_label )
94+
95+ # Set destination output for a label if op is a leaf node and (<data type>,<storage type>) == (DataPath,IOType.DISK)
96+ is_leaf = g .is_leaf (op )
97+ if is_leaf :
98+ output_op_info = op .op_info
99+ output_labels = output_op_info .get_labels (IO .OUTPUT )
100+ for output_label in output_labels :
101+ output_data_type = output_op_info .get_data_type (IO .OUTPUT , output_label )
102+ output_storage_type = output_op_info .get_storage_type (IO .OUTPUT , output_label )
103+ if issubclass (output_data_type , DataPath ) and output_storage_type == IOType .DISK :
104+ op_exec_context .output_context .set (DataPath (output_path , read_only = True ), output_label )
105+
106+ # Change the current working directory to the working directory of the operator
107+ # op_output_folder == f"{workdir}/operators/{op.uid}/{op_exec_context.get_execution_index()}/{IO.OUTPUT}"
108+ relative_output_path = Path (op_exec_context .output_context .get_group_path (IO .OUTPUT )).relative_to ("/" )
109+ op_output_folder = str (Path (workdir , relative_output_path ))
110+ os .makedirs (op_output_folder , exist_ok = True )
111+ os .chdir (op_output_folder )
112+
113+ # Execute pre_compute()
114+ print (Fore .BLUE + "Going to initiate execution of operator %s" % op .__class__ .__name__ + Fore .RESET )
115+ op .pre_compute ()
116+
117+ # Execute compute()
118+ print (
119+ Fore .GREEN
120+ + "Executing operator %s " % op .__class__ .__name__
121+ + Fore .YELLOW
122+ + "(Process ID: %s, Operator ID: %s)" % (os .getpid (), op .uid )
123+ + Fore .RESET
124+ )
125+ op .compute (op_exec_context .input_context , op_exec_context .output_context , op_exec_context )
126+
127+ # Execute post_compute()
128+ print (Fore .BLUE + "Done performing execution of operator %s\n " % op .__class__ .__name__ + Fore .RESET )
129+ op .post_compute ()
130+
131+ # Set input to next operator
132+ next_ops = g .gen_next_operators (op )
133+ for next_op in next_ops :
134+ io_map = g .get_io_map (op , next_op )
135+ if not io_map :
136+ import inspect
137+
138+ raise IOMappingError (
139+ f"No IO mappings found for { op .name } -> { next_op .name } in "
140+ f"{ inspect .getabsfile (self .app .__class__ )} "
141+ )
142+
143+ next_op_exec_context = ExecutionContext (exec_context , next_op )
144+ for (out_label , in_labels ) in io_map .items ():
145+ output = op_exec_context .output_context .get (out_label )
146+ for in_label in in_labels :
147+ next_op_exec_context .input_context .set (output , in_label )
148+ finally :
149+ # Always restore pwd even if an exception is raised (This logic can be run in an IPython environment)
150+ os .chdir (old_pwd )
146151
147152 # Remove a temporary workdir
148153 old_pwd = os .getcwd ()
0 commit comments