-
Notifications
You must be signed in to change notification settings - Fork 4
/
Restart.pyx
205 lines (158 loc) · 6.49 KB
/
Restart.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import numpy as np
import os
import shutil
import glob
#ci∂mport Grid
#cimport PrognosticVariables
try:
import cPickle as pickle
except:
import pickle as pickle # for Python 3 users
cimport ParallelMPI
cdef class Restart:
def __init__(self, dict namelist, ParallelMPI.ParallelMPI Pa, from_fields = False):
'''
Init method for Restart class. Take the namelist dictionary as an argument and determines the output path
for the restart files. If one cannot be constructed from the namelist information the restart files are placed
into the directory containing main.py. The uuid is also stored to make sure the restart files remain unique.
:param namelist:
:return:
'''
self.uuid = str(namelist['meta']['uuid'])
try:
outpath = str(os.path.join(str(namelist['output']['output_root'])
+ 'Output.' + str(namelist['meta']['simname']) + '.' + self.uuid[:]))
self.restart_path = os.path.join(outpath, 'Restart')
except:
self.restart_path = './restart.' + self.uuid[:]
if Pa.rank == 0:
try:
os.mkdir(outpath)
except:
pass
try:
os.mkdir(self.restart_path)
except:
pass
try:
self.frequency = namelist['restart']['frequency']
except:
self.frequency = 30.0
try:
self.delete_old = namelist['restart']['delete_old']
except:
self.delete_old = False
try:
times_retained_raw = namelist['restart']['times_retained']
if not type(times_retained_raw) == list:
times_retained_raw = [times_retained_raw]
# Make sure the times are strings, ie '3600' not 3600
self.times_retained = []
for time in times_retained_raw:
self.times_retained.append(str(time))
except:
self.times_retained = []
if not namelist['restart']['init_altered']:
self.is_altered = False
try:
if namelist['restart']['init_from']:
self.input_path = str(namelist['restart']['input_path'])
self.is_restart_run = True
Pa.root_print('This run is restarting from data :' + self.input_path )
else:
Pa.root_print('Not a restarted simulation.')
except:
Pa.root_print('Not a restarted simulation.')
else:
self.is_restart_run = True
self.is_altered = True
try:
self.fields_path = str(namelist['restart']['fields_path'])
# print self.fields_path
except:
Pa.root_print('Could not find path to restart fields')
Pa.kill()
#Check to make sure the path exists
if not os.path.exists(self.fields_path):
Pa.root_print("fields path does not exits! : " + self.fields_path)
Pa.kill()
return
cpdef initialize(self):
self.restart_data = {}
self.last_restart_time = 0.0
return
cpdef write(self, ParallelMPI.ParallelMPI Pa):
self.restart_data['last_restart_time'] = self.last_restart_time
#Set up path for writing restart files
path = self.restart_path + '/' + str(np.int(self.last_restart_time))
# Some preliminary renaming of directories if we are using the 'delete_old' option
if self.delete_old and Pa.rank == 0:
recent_dirs = glob.glob(self.restart_path +'/*_recent')
for recent_dir in recent_dirs:
prefix = recent_dir[:-7]
os.rename(recent_dir, prefix+'_old')
new_dirs = glob.glob(self.restart_path +'/*_new')
for new_dir in new_dirs:
prefix = new_dir[:-4]
os.rename(new_dir, prefix+'_recent')
if self.delete_old:
path = path + '_new'
if Pa.rank == 0:
if os.path.exists(path):
Pa.root_print("Restart path exits for safety not overwriting.")
self.free_memory()
return
else:
Pa.root_print("Creating directory: " + path + " for restart files.")
os.mkdir(path)
Pa.barrier()
with open(path+ '/' + str(Pa.rank) + '.pkl', 'wb') as f:
pickle.dump(self.restart_data, f,protocol=2)
# No point keeping data in dictionary so empty it now
self.free_memory()
if self.delete_old and Pa.rank == 0:
old_dirs = glob.glob(self.restart_path +'/*_old')
for old_dir in old_dirs:
trim_prefix = old_dir[len(self.restart_path)+1:-4]
if trim_prefix in self.times_retained:
os.rename(old_dir, self.restart_path+'/'+trim_prefix)
else:
shutil.rmtree(old_dir)
return
cpdef read(self, ParallelMPI.ParallelMPI Pa):
with open(self.input_path + '/' + str(Pa.rank) + '.pkl', 'rb') as f:
self.restart_data = pickle.load(f)
Pa.barrier()
# We rename the input directory in case it ends in one of the suffixes
# that is used to find files for deletion
if Pa.rank == 0:
if self.delete_old:
os.rename(self.input_path, self.input_path +'_original')
cpdef read_aux(self, ParallelMPI.ParallelMPI Pa):
with open(self.fields_path + '/' + 'aux_data.pkl', 'rb') as f:
self.restart_data = pickle.load(f)
Pa.barrier()
return
cpdef free_memory(self):
'''
Free memory associated with restart_data dictionary.
:return:
'''
self.restart_data = {}
return
cpdef cleanup(self, ParallelMPI.ParallelMPI Pa):
if Pa.rank == 0:
path = self.restart_path
originals = glob.glob(path+'/*_original')
for original in originals:
prefix = original[:-9]
os.rename(original, prefix)
recents = glob.glob(path +'/*_recent')
for recent in recents:
prefix = recent[:-7]
os.rename(recent, prefix)
new_dirs = glob.glob(path +'/*_new')
for new_dir in new_dirs:
prefix = new_dir[:-4]
os.rename(new_dir, prefix)
return