Merge lp:~simon-funke/libadjoint/online_revolve into lp:~libadjoint/libadjoint/libadjoint_python

Proposed by Simon Funke
Status: Merged
Merged at revision: 403
Proposed branch: lp:~simon-funke/libadjoint/online_revolve
Merge into: lp:~libadjoint/libadjoint/libadjoint_python
Diff against target: 1200 lines (+293/-213)
16 files modified
doc/manual/annotation.aux (+13/-11)
doc/manual/data_callbacks.aux (+6/-4)
doc/manual/data_callbacks.tex (+34/-18)
include/libadjoint/adj_adjointer_routines.h (+4/-4)
include/libadjoint/adj_constants.h (+3/-2)
include/libadjoint/adj_data_structures.h (+5/-12)
include/libadjoint/adj_petsc_data_structures.h (+4/-2)
python/libadjoint/libadjoint.py (+80/-2)
src/adj_adjointer_routines.c (+57/-92)
src/adj_core.c (+9/-0)
src/adj_debug.c (+3/-7)
src/adj_fortran.F90 (+14/-15)
src/adj_petsc_data_structures.c (+45/-9)
src/tests/test_adj_forget_forward_equation.c (+3/-4)
src/tests/test_checkpoint_revolve_multistage.c (+7/-16)
src/tests/test_checkpoint_revolve_offline.c (+6/-15)
To merge this branch: bzr merge lp:~simon-funke/libadjoint/online_revolve
Reviewer Review Type Date Requested Status
Patrick Farrell Pending
Review via email: mp+89065@code.launchpad.net

Description of the change

Second attempt for the merge request:

- Removed var_data linked list from the adjointer. Instead the uthash iteration feature is used to loop over variables.
- Instead of providing the filename to the read/write/delete cb, I now pass in the variable and let the user decide which naming convention to use. For that I also needed to introduce a
- New callback adj_vec_delete.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/manual/annotation.aux'
2--- doc/manual/annotation.aux 2011-08-09 10:52:22 +0000
3+++ doc/manual/annotation.aux 2012-01-18 15:51:24 +0000
4@@ -6,16 +6,18 @@
5 \@writefile{lot}{\contentsline {xchapter}{Annotating forward models}{7}{chapter.2}}
6 \@writefile{toc}{\contentsline {section}{\numberline {2.1}A simple example}{8}{section.2.1}}
7 \newlabel{sec:examples}{{2.1}{8}{A simple example\relax }{section.2.1}{}}
8-\@writefile{toc}{\contentsline {section}{\numberline {2.2}Existing model code}{8}{section.2.2}}
9-\@writefile{toc}{\contentsline {section}{\numberline {2.3}Annotating the model}{8}{section.2.3}}
10-\newlabel{api:adj_timestep_set_times}{{2.3.1}{8}{\texttt {adj_timestep_set_times}\label {api:adj_timestep_set_times}\relax }{subsection.2.3.1}{}}
11-\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.1}\texttt {adj_timestep_set_times}}{8}{subsection.2.3.1}}
12-\newlabel{api:adj_timestep_set_functional_dependencies}{{2.3.2}{8}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{subsection.2.3.2}{}}
13-\@writefile{toc}{\contentsline {subsection}{\numberline {2.3.2}\texttt {adj_timestep_set_functional_dependencies}}{8}{subsection.2.3.2}}
14-\newlabel{eq:functional_as_sum}{{2.1}{8}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.3.1}{}}
15-\newlabel{eq:ex_functional1}{{2.2}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.3.2}{}}
16-\newlabel{eq:ex_functional2}{{2.3}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.3.3}{}}
17-\newlabel{eq:ex_functional3}{{2.4}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.3.4}{}}
18+\@writefile{toc}{\contentsline {section}{\numberline {2.2}A nonlinear example}{8}{section.2.2}}
19+\newlabel{sec:examples}{{2.2}{8}{A nonlinear example\relax }{section.2.2}{}}
20+\@writefile{toc}{\contentsline {section}{\numberline {2.3}Existing model code}{8}{section.2.3}}
21+\@writefile{toc}{\contentsline {section}{\numberline {2.4}Annotating the model}{8}{section.2.4}}
22+\newlabel{api:adj_timestep_set_times}{{2.4.1}{8}{\texttt {adj_timestep_set_times}\label {api:adj_timestep_set_times}\relax }{subsection.2.4.1}{}}
23+\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.1}\texttt {adj_timestep_set_times}}{8}{subsection.2.4.1}}
24+\newlabel{api:adj_timestep_set_functional_dependencies}{{2.4.2}{8}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{subsection.2.4.2}{}}
25+\@writefile{toc}{\contentsline {subsection}{\numberline {2.4.2}\texttt {adj_timestep_set_functional_dependencies}}{8}{subsection.2.4.2}}
26+\newlabel{eq:functional_as_sum}{{2.1}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.4.1}{}}
27+\newlabel{eq:ex_functional1}{{2.2}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.4.2}{}}
28+\newlabel{eq:ex_functional2}{{2.3}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.4.3}{}}
29+\newlabel{eq:ex_functional3}{{2.4}{9}{\texttt {adj_timestep_set_functional_dependencies}\label {api:adj_timestep_set_functional_dependencies}\relax }{equation.2.4.4}{}}
30 \@setckpt{annotation}{
31 \setcounter{page}{10}
32 \setcounter{equation}{6}
33@@ -27,7 +29,7 @@
34 \setcounter{mpfootnote}{0}
35 \setcounter{part}{0}
36 \setcounter{chapter}{2}
37-\setcounter{section}{3}
38+\setcounter{section}{4}
39 \setcounter{subsection}{2}
40 \setcounter{subsubsection}{0}
41 \setcounter{paragraph}{0}
42
43=== modified file 'doc/manual/data_callbacks.aux'
44--- doc/manual/data_callbacks.aux 2011-11-15 22:32:33 +0000
45+++ doc/manual/data_callbacks.aux 2012-01-18 15:51:24 +0000
46@@ -43,10 +43,12 @@
47 \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.7}\texttt {ADJ_VEC_SET_RANDOM_CB}}{17}{subsubsection.3.1.3.7}}
48 \newlabel{api:ADJ_VEC_DOT_PRODUCT_CB}{{3.1.3.8}{17}{\texttt {ADJ_VEC_DOT_PRODUCT_CB}\label {api:ADJ_VEC_DOT_PRODUCT_CB}\relax }{subsubsection.3.1.3.8}{}}
49 \@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.8}\texttt {ADJ_VEC_DOT_PRODUCT_CB}}{17}{subsubsection.3.1.3.8}}
50-\newlabel{api:ADJ_VEC_TO_FILE_CB}{{3.1.3.9}{18}{\texttt {ADJ_VEC_TO_FILE_CB}\label {api:ADJ_VEC_TO_FILE_CB}\relax }{subsubsection.3.1.3.9}{}}
51-\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.9}\texttt {ADJ_VEC_TO_FILE_CB}}{18}{subsubsection.3.1.3.9}}
52-\newlabel{api:ADJ_VEC_FROM_FILE_CB}{{3.1.3.10}{18}{\texttt {ADJ_VEC_FROM_FILE_CB}\label {api:ADJ_VEC_FROM_FILE_CB}\relax }{subsubsection.3.1.3.10}{}}
53-\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.10}\texttt {ADJ_VEC_FROM_FILE_CB}}{18}{subsubsection.3.1.3.10}}
54+\newlabel{api:ADJ_VEC_WRITE_CB}{{3.1.3.9}{18}{\texttt {ADJ_VEC_WRITE_CB}\label {api:ADJ_VEC_WRITE_CB}\relax }{subsubsection.3.1.3.9}{}}
55+\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.9}\texttt {ADJ_VEC_WRITE_CB}}{18}{subsubsection.3.1.3.9}}
56+\newlabel{api:ADJ_VEC_READ_CB}{{3.1.3.10}{18}{\texttt {ADJ_VEC_READ_CB}\label {api:ADJ_VEC_READ_CB}\relax }{subsubsection.3.1.3.10}{}}
57+\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.10}\texttt {ADJ_VEC_READ_CB}}{18}{subsubsection.3.1.3.10}}
58+\newlabel{api:ADJ_VEC_DELETE_CB}{{3.1.3.11}{18}{\texttt {ADJ_VEC_DELETE_CB}\label {api:ADJ_VEC_DELETE_CB}\relax }{subsubsection.3.1.3.11}{}}
59+\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.3.11}\texttt {ADJ_VEC_DELETE_CB}}{18}{subsubsection.3.1.3.11}}
60 \@writefile{toc}{\contentsline {subsection}{\numberline {3.1.4}Matrix callbacks}{18}{subsection.3.1.4}}
61 \newlabel{sec:matrix_callbacks}{{3.1.4}{18}{Matrix callbacks\relax }{subsection.3.1.4}{}}
62 \newlabel{api:ADJ_MAT_DUPLICATE_CB}{{3.1.4.1}{18}{\texttt {ADJ_MAT_DUPLICATE_CB}\label {api:ADJ_MAT_DUPLICATE_CB}\relax }{subsubsection.3.1.4.1}{}}
63
64=== modified file 'doc/manual/data_callbacks.tex'
65--- doc/manual/data_callbacks.tex 2011-11-03 10:49:53 +0000
66+++ doc/manual/data_callbacks.tex 2012-01-18 15:51:24 +0000
67@@ -332,40 +332,56 @@
68 activated on an \refapi{adj_block} with \refapi{adj_block_set_test_hermitian},
69 or on an \refapi{adj_nonlinear_block} with \\\refapi{adj_nonlinear_block_set_test_hermitian}.
70
71-\defapiss{ADJ_VEC_TO_FILE_CB}
72-\begin{boxwithtitle}{\texttt{ADJ_VEC_TO_FILE_CB}}
73+\defapiss{ADJ_VEC_WRITE_CB}
74+\begin{boxwithtitle}{\texttt{ADJ_VEC_WRITE_CB}}
75 \begin{minipage}{\columnwidth}
76 \begin{ccode}
77- void (*vec_to_file)(adj_vector x, char* filename);
78+ void (*vec_write)(adj_variable var, adj_vector x);
79 \end{ccode}
80 \begin{fortrancode}
81- subroutine adj_vec_to_file(x, filename)
82+ subroutine adj_vec_write(var, x)
83+ type(adj_variable), intent(in), value :: var
84 type(adj_vector), intent(in), value :: x
85- character(kind=c_char), dimension(ADJ_NAME_LEN), intent(in) :: filename
86- end subroutine adj_vec_to_file
87+ end subroutine adj_vec_write
88 \end{fortrancode}
89 \end{minipage}
90 \end{boxwithtitle}
91-This data callback saves the provided vector into a file named \texttt{filename} on disk.
92+This data callback saves the provided vector containing variable \texttt{var} to disk.
93
94 When necessary: If a checkpointing scheme is used.
95
96-
97-\defapiss{ADJ_VEC_FROM_FILE_CB}
98-\begin{boxwithtitle}{\texttt{ADJ_VEC_FROM_FILE_CB}}
99+\defapiss{ADJ_VEC_READ_CB}
100+\begin{boxwithtitle}{\texttt{ADJ_VEC_READ_CB}}
101 \begin{minipage}{\columnwidth}
102 \begin{ccode}
103- void (*vec_from_file)(adj_vector* x, char *filename);
104+ void (*vec_read)(adj_variable var, adj_vector* x);
105 \end{ccode}
106 \begin{fortrancode}
107- subroutine adj_vec_from_file(x, filename)
108+ subroutine adj_vec_read(var, x)
109+ type(adj_variable), intent(in), value :: var
110 type(adj_vector), intent(out) :: x
111- character(kind=c_char), dimension(ADJ_NAME_LEN), intent(in) :: filename
112- end subroutine adj_vec_from_file
113-\end{fortrancode}
114-\end{minipage}
115-\end{boxwithtitle}
116-This data callback loads the vector from file \texttt{filename} on disk.
117+ end subroutine adj_vec_read
118+\end{fortrancode}
119+\end{minipage}
120+\end{boxwithtitle}
121+This data callback loads the vector containing variable \texttt{var} from disk.
122+
123+When necessary: If a checkpointing scheme is used.
124+
125+\defapiss{ADJ_VEC_DELETE_CB}
126+\begin{boxwithtitle}{\texttt{ADJ_VEC_DELETE_CB}}
127+\begin{minipage}{\columnwidth}
128+\begin{ccode}
129+ void (*vec_delete)(adj_variable var)
130+\end{ccode}
131+\begin{fortrancode}
132+ subroutine adj_vec_delete(var)
133+ type(adj_variable), intent(in), value :: var
134+ end subroutine adj_vec_delete
135+\end{fortrancode}
136+\end{minipage}
137+\end{boxwithtitle}
138+This data callback deletes the file that stores variable \texttt{var}.
139
140 When necessary: If a checkpointing scheme is used.
141
142
143=== modified file 'include/libadjoint/adj_adjointer_routines.h'
144--- include/libadjoint/adj_adjointer_routines.h 2012-01-16 15:47:58 +0000
145+++ include/libadjoint/adj_adjointer_routines.h 2012-01-18 15:51:24 +0000
146@@ -64,12 +64,12 @@
147 int adj_has_variable_value_disk(adj_adjointer* adjointer, adj_variable var);
148 int adj_is_variable_memory_checkpoint(adj_adjointer* adjointer, adj_variable var);
149 int adj_is_variable_disk_checkpoint(adj_adjointer* adjointer, adj_variable var);
150-int adj_forget_variable_value(adj_adjointer* adjointer, adj_variable_data* data);
151+int adj_forget_variable_value(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data);
152 int adj_forget_variable_value_from_memory(adj_adjointer* adjointer, adj_variable_data* data);
153-int adj_forget_variable_value_from_disk(adj_adjointer* adjointer, adj_variable_data* data);
154-int adj_destroy_variable_data(adj_adjointer* adjointer, adj_variable_data* data);
155+int adj_forget_variable_value_from_disk(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data);
156+int adj_destroy_variable_data(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data);
157 int adj_add_new_hash_entry(adj_adjointer* adjointer, adj_variable* var, adj_variable_data** data);
158-int adj_record_variable_core_disk(adj_adjointer* adjointer, adj_variable_data* data_ptr, adj_storage_data storage);
159+int adj_record_variable_core_disk(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data_ptr, adj_storage_data storage);
160 int adj_record_variable_core_memory(adj_adjointer* adjointer, adj_variable_data* data_ptr, adj_storage_data storage);
161 int adj_record_variable_compare(adj_adjointer* adjointer, adj_variable_data* data_ptr, adj_variable var, adj_storage_data storage);
162
163
164=== modified file 'include/libadjoint/adj_constants.h'
165--- include/libadjoint/adj_constants.h 2011-11-10 20:59:12 +0000
166+++ include/libadjoint/adj_constants.h 2012-01-18 15:51:24 +0000
167@@ -69,8 +69,9 @@
168 #define ADJ_VEC_GET_NORM_CB 16
169 #define ADJ_VEC_DOT_PRODUCT_CB 17
170 #define ADJ_VEC_SET_RANDOM_CB 18
171-#define ADJ_VEC_TO_FILE_CB 19
172-#define ADJ_VEC_FROM_FILE_CB 20
173+#define ADJ_VEC_WRITE_CB 19
174+#define ADJ_VEC_READ_CB 20
175+#define ADJ_VEC_DELETE_CB 21
176
177 #define ADJ_MAT_DUPLICATE_CB 30
178 #define ADJ_MAT_AXPY_CB 31
179
180=== modified file 'include/libadjoint/adj_data_structures.h'
181--- include/libadjoint/adj_data_structures.h 2012-01-16 15:47:58 +0000
182+++ include/libadjoint/adj_data_structures.h 2012-01-18 15:51:24 +0000
183@@ -96,12 +96,11 @@
184 /* for ADJ_STORAGE_MEMORY */
185 int storage_memory_type; /* ADJ_STORAGE_MEMORY_COPY or ADJ_STORAGE_MEMORY_INCREF */
186 int storage_memory_has_value;
187- int storage_memory_is_checkpoint; /* checkpoints are not deleted by adj_forget_forward_equation */
188+ int storage_memory_is_checkpoint; /* memory checkpoints are not deleted by adj_forget_forward_equation */
189
190 /* for ADJ_STORAGE_DISK */
191 int storage_disk_has_value;
192- int storage_disk_is_checkpoint; /* checkpoints are not deleted by adj_forget_forward_equation */
193- char storage_disk_filename[ADJ_NAME_LEN];
194+ int storage_disk_is_checkpoint; /* disk checkpoints are not deleted by adj_forget_forward_equation */
195
196 /* POD, temporal interpolation, ... */
197 } adj_storage_data;
198@@ -132,12 +131,6 @@
199
200 typedef struct
201 {
202- adj_variable_data* firstnode;
203- adj_variable_data* lastnode;
204-} adj_variable_data_list;
205-
206-typedef struct
207-{
208 void (*vec_duplicate)(adj_vector x, adj_vector *newx);
209 void (*vec_axpy)(adj_vector *y, adj_scalar alpha, adj_vector x);
210 void (*vec_destroy)(adj_vector *x);
211@@ -147,8 +140,9 @@
212 void (*vec_get_norm)(adj_vector x, adj_scalar* norm);
213 void (*vec_dot_product)(adj_vector x, adj_vector y, adj_scalar* val);
214 void (*vec_set_random)(adj_vector* x);
215- void (*vec_to_file)(adj_vector x, char* filename);
216- void (*vec_from_file)(adj_vector* x, char *filename);
217+ void (*vec_write)(adj_variable var, adj_vector x);
218+ void (*vec_read)(adj_variable var, adj_vector* x);
219+ void (*vec_delete)(adj_variable var);
220
221 void (*mat_duplicate)(adj_matrix matin, adj_matrix *matout);
222 void (*mat_axpy)(adj_matrix *Y, adj_scalar alpha, adj_matrix X);
223@@ -286,7 +280,6 @@
224 adj_revolve_data revolve_data; /* A data struct for revolve related information */
225
226 adj_variable_hash* varhash; /* The hash table for looking up information about variables */
227- adj_variable_data_list vardata; /* We also store a linked list so we can walk all our variable data */
228
229 int options[ADJ_NO_OPTIONS]; /* Pretty obvious */
230
231
232=== modified file 'include/libadjoint/adj_petsc_data_structures.h'
233--- include/libadjoint/adj_petsc_data_structures.h 2011-08-30 19:15:58 +0000
234+++ include/libadjoint/adj_petsc_data_structures.h 2012-01-18 15:51:24 +0000
235@@ -2,6 +2,7 @@
236 #define ADJ_PETSC_DATA_STRUCTURES_H
237
238 #include <string.h>
239+#include <stdio.h>
240 #include <sys/time.h>
241 #include <sys/types.h>
242 #include <unistd.h>
243@@ -24,8 +25,9 @@
244 void petsc_vec_getnorm_proc(adj_vector vec, adj_scalar* norm);
245 void petsc_vec_set_random_proc(adj_vector* x);
246 void petsc_vec_dot_product_proc(adj_vector x, adj_vector y, adj_scalar* val);
247-void petsc_vec_to_file_proc(adj_vector x, char* filename);
248-void petsc_vec_from_file_proc(adj_vector* x, char* filename);
249+void petsc_vec_write_proc(adj_variable var, adj_vector x);
250+void petsc_vec_read_proc(adj_variable var, adj_vector* x);
251+void petsc_vec_delete_proc(adj_variable var);
252
253 void petsc_mat_getvec_proc(adj_matrix mat, adj_vector *left);
254 void petsc_mat_axpy_proc(adj_matrix *Y, adj_scalar alpha, adj_matrix X);
255
256=== modified file 'python/libadjoint/libadjoint.py'
257--- python/libadjoint/libadjoint.py 2012-01-16 15:47:58 +0000
258+++ python/libadjoint/libadjoint.py 2012-01-18 15:51:24 +0000
259@@ -294,10 +294,12 @@
260
261 class DiskStorage(Storage):
262 '''Wrapper class for Vectors that contains additional information for storing the vector values in memory.'''
263- def __init__(self, vec):
264+ def __init__(self, vec, cs=False):
265 self.storage_data = clib.adj_storage_data()
266 self.c_object = self.storage_data
267- clib.adj_storage_disk_incref(vec.as_adj_vector(), self.storage_data)
268+ clib.adj_storage_disk(vec.as_adj_vector(), self.storage_data)
269+
270+ self.set_checkpoint(cs)
271
272 # Ensure that the storage object always holds a reference to the vec
273 self.vec = vec
274@@ -617,6 +619,9 @@
275 self.vec_set_random_type = ctypes.CFUNCTYPE(None, ctypes.POINTER(clib.adj_vector))
276 self.vec_set_values_type = ctypes.CFUNCTYPE(None, ctypes.POINTER(clib.adj_vector), ctypes.POINTER(adj_scalar))
277 self.vec_get_size_type = ctypes.CFUNCTYPE(None, clib.adj_vector, ctypes.POINTER(ctypes.c_int))
278+ self.vec_write_type = ctypes.CFUNCTYPE(None, clib.adj_variable, clib.adj_vector)
279+ self.vec_read_type = ctypes.CFUNCTYPE(None, clib.adj_variable, ctypes.POINTER(clib.adj_vector))
280+ self.vec_delete_type = ctypes.CFUNCTYPE(None, clib.adj_variable)
281 self.mat_duplicate_type = ctypes.CFUNCTYPE(None, clib.adj_matrix, ctypes.POINTER(clib.adj_matrix))
282 self.mat_destroy_type = ctypes.CFUNCTYPE(None, ctypes.POINTER(clib.adj_matrix))
283 self.mat_axpy_type = ctypes.CFUNCTYPE(None, ctypes.POINTER(clib.adj_matrix), adj_scalar, clib.adj_matrix)
284@@ -723,6 +728,25 @@
285 finally:
286 references_taken.append(storage.vec)
287
288+ # At this point we should also reregister the read and the delete callbacks.
289+ # Note that the initial callback implementation could not access
290+ # the user implementation of the read() and delete() functions, and but here we can.
291+ def __vec_read_callback__(adj_var, adj_vec_ptr):
292+ var = Variable(var=adj_var)
293+ y = storage.vec.__class__.read(var)
294+ # Increase the reference counter of the new object to protect it from deallocation at the end of the callback
295+ references_taken.append(y)
296+ adj_vec_ptr[0].ptr = python_utils.c_ptr(y)
297+ adj_vec_ptr[0].klass = 0
298+ adj_vec_ptr[0].flags = 0
299+
300+ def __vec_delete_callback__(adj_var):
301+ var = Variable(var=adj_var)
302+ storage.vec.__class__.delete(var)
303+
304+ self.__register_data_callback__('ADJ_VEC_DELETE_CB', __vec_delete_callback__)
305+ self.__register_data_callback__('ADJ_VEC_READ_CB', __vec_read_callback__)
306+
307 def evaluate_functional(self, functional, timestep):
308 '''evaluate_functional(self, functional, timestep)
309
310@@ -850,6 +874,9 @@
311 self.__register_data_callback__('ADJ_VEC_SET_RANDOM_CB', self.__vec_set_random_callback__)
312 self.__register_data_callback__('ADJ_VEC_SET_VALUES_CB', self.__vec_set_values_callback__)
313 self.__register_data_callback__('ADJ_VEC_GET_SIZE_CB', self.__vec_get_size_callback__)
314+ self.__register_data_callback__('ADJ_VEC_WRITE_CB', self.__vec_write_callback__)
315+ self.__register_data_callback__('ADJ_VEC_READ_CB', self.__vec_read_callback__)
316+ self.__register_data_callback__('ADJ_VEC_DELETE_CB', self.__vec_delete_callback__)
317 self.__register_data_callback__('ADJ_MAT_DUPLICATE_CB', self.__mat_duplicate_callback__)
318 self.__register_data_callback__('ADJ_MAT_DESTROY_CB', self.__mat_destroy_callback__)
319 self.__register_data_callback__('ADJ_MAT_AXPY_CB', self.__mat_axpy_callback__)
320@@ -892,6 +919,9 @@
321 'ADJ_VEC_SET_RANDOM_CB': self.vec_set_random_type,
322 'ADJ_VEC_SET_VALUES_CB': self.vec_set_values_type,
323 'ADJ_VEC_GET_SIZE_CB': self.vec_get_size_type,
324+ 'ADJ_VEC_WRITE_CB': self.vec_write_type,
325+ 'ADJ_VEC_READ_CB': self.vec_read_type,
326+ "ADJ_VEC_DELETE_CB": self.vec_delete_type,
327 "ADJ_MAT_DUPLICATE_CB": self.mat_duplicate_type,
328 "ADJ_MAT_DESTROY_CB": self.mat_destroy_type,
329 "ADJ_MAT_AXPY_CB": self.mat_axpy_type,
330@@ -1099,6 +1129,34 @@
331 sz[0] = y.size()
332
333 @staticmethod
334+ def __vec_write_callback__(adj_var, adj_vec):
335+ var = Variable(var=adj_var)
336+ vec = vector(adj_vec)
337+ vec.write(var)
338+
339+ @staticmethod
340+ def __vec_read_callback__(adj_var, adj_vec_ptr):
341+ raise exceptions.LibadjointErrorInvalidInputs(
342+ 'Internal error: called vec_read callback before recording any variables.')
343+
344+ @staticmethod
345+ def __vec_delete_callback__(adj_var):
346+ raise exceptions.LibadjointErrorInvalidInputs(
347+ 'Internal error: called vec_delete callback before recording any variables.')
348+
349+ print "To be implemented"
350+ assert(False)
351+ vec = vector(adj_vec_ptr[0])
352+
353+ # Do the corresponding decref of the object, so that the Python GC can pick it up
354+ try:
355+ references_taken.remove(vec)
356+ except:
357+ print vec.data
358+ print references_taken
359+ raise
360+
361+ @staticmethod
362 def __mat_duplicate_callback__(adj_mat, adj_mat_ptr):
363 mat = matrix(adj_mat)
364 new_mat = mat.duplicate()
365@@ -1202,6 +1260,26 @@
366 raise exceptions.LibadjointErrorNeedCallback(
367 'Class '+self.__class__.__name__+' has no dot_product() method')
368
369+ @staticmethod
370+ def read(var):
371+ '''This method must return a vector containing the values of var from disk.'''
372+
373+ raise exceptions.LibadjointErrorNeedCallback(
374+ 'Class Vector has no read() method')
375+
376+ @staticmethod
377+ def delete(var):
378+ '''This method must delete the vector containing the values of var from disk.'''
379+
380+ raise exceptions.LibadjointErrorNeedCallback(
381+ 'Class Vector has no delete() method')
382+
383+ def write(self, var):
384+ '''This method must write this vector as values of var to disk.'''
385+
386+ raise exceptions.LibadjointErrorNeedCallback(
387+ 'Class '+self.__class__.__name__+' has no write() method')
388+
389 def as_adj_vector(self):
390 '''as_adj_vector(self)
391
392
393=== modified file 'src/adj_adjointer_routines.c'
394--- src/adj_adjointer_routines.c 2012-01-18 15:18:28 +0000
395+++ src/adj_adjointer_routines.c 2012-01-18 15:51:24 +0000
396@@ -12,8 +12,6 @@
397 adjointer->timestep_data = NULL;
398
399 adjointer->varhash = NULL;
400- adjointer->vardata.firstnode = NULL;
401- adjointer->vardata.lastnode = NULL;
402
403 adjointer->callbacks.vec_duplicate = NULL;
404 adjointer->callbacks.vec_axpy = NULL;
405@@ -24,8 +22,9 @@
406 adjointer->callbacks.vec_get_norm = NULL;
407 adjointer->callbacks.vec_set_random = NULL;
408 adjointer->callbacks.vec_dot_product = NULL;
409- adjointer->callbacks.vec_to_file = NULL;
410- adjointer->callbacks.vec_from_file = NULL;
411+ adjointer->callbacks.vec_write = NULL;
412+ adjointer->callbacks.vec_read = NULL;
413+ adjointer->callbacks.vec_delete = NULL;
414
415 adjointer->callbacks.mat_duplicate = NULL;
416 adjointer->callbacks.mat_axpy = NULL;
417@@ -72,6 +71,7 @@
418 {
419 int i;
420 int ierr;
421+ adj_variable_hash* varhash;
422 adj_variable_data* data_ptr;
423 adj_variable_data* data_ptr_tmp;
424 adj_op_callback* cb_ptr;
425@@ -106,10 +106,10 @@
426 free(adjointer->timestep_data);
427 }
428
429- data_ptr = adjointer->vardata.firstnode;
430- while (data_ptr != NULL)
431+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
432 {
433- ierr = adj_destroy_variable_data(adjointer, data_ptr);
434+ data_ptr=varhash->data;
435+ ierr = adj_destroy_variable_data(adjointer, varhash->variable, data_ptr);
436 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
437 data_ptr_tmp = data_ptr;
438 data_ptr = data_ptr->next;
439@@ -688,11 +688,6 @@
440 return adj_chkierr_auto(ADJ_ERR_NEED_VALUE);
441 }
442
443- /* Create the filename in case we need to store/load from disk */
444- char filename[ADJ_NAME_LEN];
445- adj_variable_str(var, filename, ADJ_NAME_LEN);
446- strncat(filename, ".dat", 4);
447-
448 /* Case 1: variable is on disk and we want to checkpoint it in disk */
449 if ((cs == ADJ_CHECKPOINT_STORAGE_DISK) && (var_data->storage.storage_disk_has_value == ADJ_TRUE))
450 {
451@@ -721,12 +716,12 @@
452 else if (cs == ADJ_CHECKPOINT_STORAGE_MEMORY && (var_data->storage.storage_memory_has_value != ADJ_TRUE))
453 {
454 /* Check for the required callbacks */
455- if (adjointer->callbacks.vec_from_file == NULL)
456+ if (adjointer->callbacks.vec_read == NULL)
457 {
458- strncpy(adj_error_msg, "Need the vec_from_file data callback, but it hasn't been supplied.", ADJ_ERROR_MSG_BUF);
459+ strncpy(adj_error_msg, "Need the ADJ_VEC_READ_CB data callback, but it hasn't been supplied.", ADJ_ERROR_MSG_BUF);
460 return adj_chkierr_auto(ADJ_ERR_NEED_CALLBACK);
461 }
462- adjointer->callbacks.vec_from_file(&(var_data->storage.value), filename);
463+ adjointer->callbacks.vec_read(var, &(var_data->storage.value));
464 var_data->storage.storage_memory_has_value=ADJ_TRUE;
465
466 var_data->storage.storage_memory_is_checkpoint = ADJ_TRUE;
467@@ -755,7 +750,7 @@
468 (adjointer->revolve_data.current_action != CACTION_FIRSTRUN))
469 {
470 adj_variable_str(equation.variable, buf, ADJ_NAME_LEN);
471- snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "The adjointer and revolve are not consistent (in adj_register_equation of variable %s). This can happen when one tries to register an equation after solving the first adjoint equation.", buf);
472+ snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "The adjointer and revolve are not consistent (in adj_register_equation of variable %s). Did you register an equation after solving the first adjoint equation?", buf);
473 return adj_chkierr_auto(ADJ_ERR_REVOLVE_ERROR);
474 }
475 }
476@@ -1002,15 +997,7 @@
477 else if (storage.storage_memory_has_value && !data_ptr->storage.storage_memory_has_value)
478 return adj_record_variable_core_memory(adjointer, data_ptr, storage);
479 else if (storage.storage_disk_has_value && !data_ptr->storage.storage_disk_has_value)
480- {
481- /* Generate the filename */
482- char filename[ADJ_NAME_LEN];
483- adj_variable_str(var, filename, ADJ_NAME_LEN);
484- strncat(filename, ".dat", 4);
485- strncpy(storage.storage_disk_filename, filename, ADJ_NAME_LEN);
486-
487- return adj_record_variable_core_disk(adjointer, data_ptr, storage);
488- }
489+ return adj_record_variable_core_disk(adjointer, var, data_ptr, storage);
490 else
491 /* Sorry for the slight mess. The easiest way to understand this block is to build a 2x2 graph of
492 compare and overwrite:
493@@ -1044,7 +1031,7 @@
494 {
495 int record_ierr;
496
497- ierr = adj_forget_variable_value(adjointer, data_ptr);
498+ ierr = adj_forget_variable_value(adjointer, var, data_ptr);
499 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
500
501 record_ierr = adj_record_variable_core_memory(adjointer, data_ptr, storage); /* Overwrite the result anyway */
502@@ -1064,7 +1051,7 @@
503 {
504 if (storage.overwrite)
505 {
506- ierr = adj_forget_variable_value(adjointer, data_ptr);
507+ ierr = adj_forget_variable_value(adjointer, var, data_ptr);
508 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
509 return adj_record_variable_core_memory(adjointer, data_ptr, storage);
510 }
511@@ -1131,11 +1118,11 @@
512 }
513
514 /* The core routine to record a variable to disk */
515-int adj_record_variable_core_disk(adj_adjointer* adjointer, adj_variable_data* data_ptr, adj_storage_data storage)
516+int adj_record_variable_core_disk(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data_ptr, adj_storage_data storage)
517 {
518- if (adjointer->callbacks.vec_to_file == NULL)
519+ if (adjointer->callbacks.vec_write == NULL)
520 {
521- snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "You have asked to record a value to disk, but no ADJ_VEC_TO_FILE_CB callback has been provided.");
522+ snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "You have asked to record a value to disk, but no ADJ_VEC_WRITE_CB callback has been provided.");
523 return adj_chkierr_auto(ADJ_ERR_NEED_CALLBACK);
524 }
525
526@@ -1153,8 +1140,7 @@
527
528 data_ptr->storage.storage_disk_has_value = storage.storage_disk_has_value;
529 data_ptr->storage.storage_disk_is_checkpoint = storage.storage_disk_is_checkpoint;
530- strncpy(data_ptr->storage.storage_disk_filename, storage.storage_disk_filename, ADJ_NAME_LEN);
531- adjointer->callbacks.vec_to_file(storage.value, data_ptr->storage.storage_disk_filename);
532+ adjointer->callbacks.vec_write(var, storage.value);
533
534 return ADJ_OK;
535 }
536@@ -1315,11 +1301,14 @@
537 case ADJ_VEC_SET_RANDOM_CB:
538 adjointer->callbacks.vec_set_random = (void(*)(adj_vector* x)) fn;
539 break;
540- case ADJ_VEC_TO_FILE_CB:
541- adjointer->callbacks.vec_to_file = (void(*)(adj_vector x, char* filename)) fn;
542- break;
543- case ADJ_VEC_FROM_FILE_CB:
544- adjointer->callbacks.vec_from_file = (void(*)(adj_vector* x, char* filename)) fn;
545+ case ADJ_VEC_WRITE_CB:
546+ adjointer->callbacks.vec_write = (void(*)(adj_variable, adj_vector x)) fn;
547+ break;
548+ case ADJ_VEC_READ_CB:
549+ adjointer->callbacks.vec_read = (void(*)(adj_variable var, adj_vector* x)) fn;
550+ break;
551+ case ADJ_VEC_DELETE_CB:
552+ adjointer->callbacks.vec_delete = (void(*)(adj_variable var)) fn;
553 break;
554
555 case ADJ_MAT_DUPLICATE_CB:
556@@ -1431,6 +1420,7 @@
557
558 int adj_forget_adjoint_equation(adj_adjointer* adjointer, int equation)
559 {
560+ adj_variable_hash* varhash;
561 adj_variable_data* data;
562 int should_we_delete;
563 int i;
564@@ -1439,8 +1429,8 @@
565
566 if (adjointer->options[ADJ_ACTIVITY] == ADJ_ACTIVITY_NOTHING) return ADJ_OK;
567
568- /* Dont delete any variables if we want to compare in the revolve replays */
569- if (adjointer->revolve_data.overwrite==ADJ_TRUE)
570+ /* Do not delete any variables if we want to compare forward variables with the revolve replay */
571+ if (adjointer->revolve_data.overwrite == ADJ_TRUE)
572 return ADJ_OK;
573
574 if (equation >= adjointer->nequations)
575@@ -1449,9 +1439,9 @@
576 return adj_chkierr_auto(ADJ_ERR_INVALID_INPUTS);
577 }
578
579- data = adjointer->vardata.firstnode;
580- while (data != NULL)
581+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
582 {
583+ data = varhash->data;
584 if (data->storage.storage_memory_has_value || data->storage.storage_disk_has_value)
585 {
586 should_we_delete = 1;
587@@ -1485,7 +1475,7 @@
588 /* Forget only non-checkpoint variables */
589 if (data->storage.storage_disk_has_value && !data->storage.storage_disk_is_checkpoint)
590 {
591- ierr = adj_forget_variable_value_from_disk(adjointer, data);
592+ ierr = adj_forget_variable_value_from_disk(adjointer, varhash->variable, data);
593 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
594 }
595 if (data->storage.storage_memory_has_value && !data->storage.storage_memory_is_checkpoint)
596@@ -1496,7 +1486,6 @@
597 }
598 }
599
600- data = data->next;
601 }
602
603 return ADJ_OK;
604@@ -1521,6 +1510,7 @@
605 */
606 int adj_forget_forward_equation_until(adj_adjointer* adjointer, int equation, int last_equation)
607 {
608+ adj_variable_hash* varhash;
609 adj_variable_data* data;
610 int should_we_delete;
611 int i;
612@@ -1534,23 +1524,16 @@
613 return adj_chkierr_auto(ADJ_ERR_INVALID_INPUTS);
614 }
615
616- data = adjointer->vardata.firstnode;
617-
618- while (data != NULL)
619+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
620 {
621+ data = varhash->data;
622 /* Only forget forward variables */
623 if (data->type != ADJ_FORWARD) /* Skip adjoint or TLM variables. */
624- {
625- data = data->next;
626 continue;
627- }
628
629 /* Only forget forward variables that are computed at equations <= equation */
630 if (data->equation>equation)
631- {
632- data = data->next;
633 continue;
634- }
635
636 if (data->storage.storage_memory_has_value || data->storage.storage_disk_has_value)
637 {
638@@ -1593,7 +1576,7 @@
639 /* Forget only non-checkpoint variables */
640 if (data->storage.storage_disk_has_value && !data->storage.storage_disk_is_checkpoint)
641 {
642- ierr = adj_forget_variable_value_from_disk(adjointer, data);
643+ ierr = adj_forget_variable_value_from_disk(adjointer, varhash->variable, data);
644 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
645 }
646 if (data->storage.storage_memory_has_value && !data->storage.storage_memory_is_checkpoint)
647@@ -1604,7 +1587,6 @@
648 }
649 }
650
651- data = data->next;
652 }
653
654 return ADJ_OK;
655@@ -1612,6 +1594,7 @@
656
657 int adj_forget_tlm_equation(adj_adjointer* adjointer, int equation)
658 {
659+ adj_variable_hash* varhash;
660 adj_variable_data* data;
661 int should_we_delete;
662 int i;
663@@ -1625,16 +1608,13 @@
664 return adj_chkierr_auto(ADJ_ERR_INVALID_INPUTS);
665 }
666
667- data = adjointer->vardata.firstnode;
668-
669- while (data != NULL)
670+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
671 {
672+ data = varhash->data;
673+
674 /* Only forget forward variables */
675 if (data->type != ADJ_TLM) /* Skip anything other than TLM variables.. */
676- {
677- data = data->next;
678 continue;
679- }
680
681 if (data->storage.storage_memory_has_value || data->storage.storage_disk_has_value)
682 {
683@@ -1679,7 +1659,6 @@
684 }
685 }
686
687- data = data->next;
688 }
689
690 return ADJ_OK;
691@@ -1803,12 +1782,14 @@
692 /* Disk storage */
693 else if(data_ptr->storage.storage_disk_has_value)
694 {
695- if (adjointer->callbacks.vec_from_file == NULL)
696+ if (adjointer->callbacks.vec_read == NULL)
697 {
698- snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "You have asked to get a value from disk, but no ADJ_VEC_FROM_FILE_CB callback has been provided.");
699+ snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "You have asked to get a value from disk, but no ADJ_VEC_READ_CB callback has been provided.");
700 return adj_chkierr_auto(ADJ_ERR_NEED_CALLBACK);
701 }
702- adjointer->callbacks.vec_from_file(value, data_ptr->storage.storage_disk_filename);
703+ adjointer->callbacks.vec_read(var, value);
704+ data_ptr->storage.storage_memory_has_value = ADJ_TRUE;
705+ data_ptr->storage.value = *value;
706 }
707 return ADJ_OK;
708 }
709@@ -1895,13 +1876,13 @@
710 return data_ptr->storage.storage_memory_is_checkpoint;
711 }
712
713-int adj_forget_variable_value(adj_adjointer* adjointer, adj_variable_data* data)
714+int adj_forget_variable_value(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data)
715 {
716 int ierr;
717
718 if (data->storage.storage_disk_has_value)
719 {
720- ierr = adj_forget_variable_value_from_disk(adjointer, data);
721+ ierr = adj_forget_variable_value_from_disk(adjointer, var, data);
722 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
723 }
724 if (data->storage.storage_memory_has_value)
725@@ -1912,22 +1893,18 @@
726 return ADJ_OK;
727 }
728
729-int adj_forget_variable_value_from_disk(adj_adjointer* adjointer, adj_variable_data* data)
730+int adj_forget_variable_value_from_disk(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data)
731 {
732- int ierr;
733+ if (adjointer->callbacks.vec_delete == NULL)
734+ {
735+ strncpy(adj_error_msg, "Need ADJ_VEC_DELETE_CB data callback.", ADJ_ERROR_MSG_BUF);
736+ return adj_chkierr_auto(ADJ_ERR_NEED_CALLBACK);
737+ }
738
739 assert(data->storage.storage_disk_has_value);
740- if (access(data->storage.storage_disk_filename, W_OK) == -1) {
741- char buf[ADJ_NAME_LEN];
742- adj_variable_str(adjointer->equations[data->equation].variable, buf, ADJ_NAME_LEN);
743-
744- ierr = ADJ_ERR_INVALID_INPUTS;
745- snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "Can not access variable %s in file '%s'.", buf, data->storage.storage_disk_filename);
746- return adj_chkierr_auto(ierr);
747- }
748
749 data->storage.storage_disk_has_value = ADJ_FALSE;
750- remove(data->storage.storage_disk_filename);
751+ adjointer->callbacks.vec_delete(var);
752 return ADJ_OK;
753 }
754
755@@ -1935,7 +1912,7 @@
756 {
757 if (adjointer->callbacks.vec_destroy == NULL)
758 {
759- strncpy(adj_error_msg, "Need vec_destroy data callback.", ADJ_ERROR_MSG_BUF);
760+ strncpy(adj_error_msg, "Need ADJ_VEC_DESTROY_CB data callback.", ADJ_ERROR_MSG_BUF);
761 return adj_chkierr_auto(ADJ_ERR_NEED_CALLBACK);
762 }
763
764@@ -1946,7 +1923,7 @@
765 return ADJ_OK;
766 }
767
768-int adj_destroy_variable_data(adj_adjointer* adjointer, adj_variable_data* data)
769+int adj_destroy_variable_data(adj_adjointer* adjointer, adj_variable var, adj_variable_data* data)
770 {
771
772 if (data->ntargeting_equations > 0)
773@@ -1974,7 +1951,7 @@
774 }
775
776 if (data->storage.storage_memory_has_value || data->storage.storage_disk_has_value)
777- return adj_forget_variable_value(adjointer, data);
778+ return adj_forget_variable_value(adjointer, var, data);
779
780 return ADJ_OK;
781 }
782@@ -2156,18 +2133,6 @@
783 ierr = adj_add_variable_data(&(adjointer->varhash), var, *data);
784 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
785
786- /* and add to the data list */
787- if (adjointer->vardata.firstnode == NULL)
788- {
789- adjointer->vardata.firstnode = *data;
790- adjointer->vardata.lastnode = *data;
791- }
792- else
793- {
794- adjointer->vardata.lastnode->next = *data;
795- adjointer->vardata.lastnode = *data;
796- }
797-
798 return ADJ_OK;
799 }
800
801
802=== modified file 'src/adj_core.c'
803--- src/adj_core.c 2012-01-16 15:47:58 +0000
804+++ src/adj_core.c 2012-01-18 15:51:24 +0000
805@@ -455,6 +455,15 @@
806 oldcapo = revolve_getoldcapo(adjointer->revolve_data.revolve);
807 capo = revolve_getcapo(adjointer->revolve_data.revolve);
808
809+ /* If revolve advances to a timestep larger than ntimeteps-1,
810+ * then the user claimed in the revolve settings to solve for more timesteps then we actually did.
811+ */
812+ if (capo > adjointer->ntimesteps-1)
813+ {
814+ snprintf(adj_error_msg, ADJ_ERROR_MSG_BUF, "Revolve expected %i timesteps but only %i were annotated.", capo+1, adjointer->ntimesteps);
815+ return adj_chkierr_auto(ADJ_ERR_INVALID_INPUTS);
816+ }
817+
818 ierr = adj_timestep_start_equation(adjointer, oldcapo, &start_eqn);
819 if (ierr != ADJ_OK) return adj_chkierr_auto(ierr);
820 ierr = adj_timestep_end_equation(adjointer, capo-1, &end_eqn);
821
822=== modified file 'src/adj_debug.c'
823--- src/adj_debug.c 2011-11-10 22:18:55 +0000
824+++ src/adj_debug.c 2012-01-18 15:51:24 +0000
825@@ -136,6 +136,7 @@
826
827 if (cp_num>0)
828 {
829+ adj_variable_hash* varhash;
830 adj_variable_data* data;
831
832 /* The first checkpoint equation must be zero, otherwise */
833@@ -147,16 +148,12 @@
834 }
835
836 /* Check we have the required variables for the adjoint equations */
837- data = adjointer->vardata.firstnode;
838- /* Loop over every variable */
839- while (data != NULL)
840+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
841 {
842+ data = varhash->data;
843 /* We are only interested in forward variables */
844 if (data->equation < 0)
845- {
846- data = data->next;
847 continue;
848- }
849
850 /* Find out in which checkpoint slot the variable is computed */
851 for (cp_iter=0; cp_iter < cp_num-1; cp_iter++)
852@@ -187,7 +184,6 @@
853 }
854 }
855
856- data = data->next;
857 }
858 }
859
860
861=== modified file 'src/adj_fortran.F90'
862--- src/adj_fortran.F90 2012-01-16 15:47:58 +0000
863+++ src/adj_fortran.F90 2012-01-18 15:51:24 +0000
864@@ -71,8 +71,9 @@
865 type(c_funptr) :: vec_get_norm
866 type(c_funptr) :: vec_dot_product
867 type(c_funptr) :: vec_set_random
868- type(c_funptr) :: vec_to_file
869- type(c_funptr) :: vec_from_file
870+ type(c_funptr) :: vec_write
871+ type(c_funptr) :: vec_read
872+ type(c_funptr) :: vec_delete
873
874 type(c_funptr) :: mat_duplicate
875 type(c_funptr) :: mat_axpy
876@@ -81,11 +82,6 @@
877 type(c_funptr) :: solve
878 end type adj_data_callbacks
879
880- type, bind(c) :: adj_variable_data_list
881- type(c_ptr) :: firstnode
882- type(c_ptr) :: lastnode
883- end type adj_variable_data_list
884-
885 type, bind(c) :: adj_op_callback_list
886 type(c_ptr) :: firstnode
887 type(c_ptr) :: lastnode
888@@ -135,7 +131,6 @@
889 type(adj_revolve_data) :: revolve_data
890
891 type(c_ptr) :: varhash
892- type(adj_variable_data_list) :: vardata
893
894 integer(kind=c_int), dimension(ADJ_NO_OPTIONS) :: options
895
896@@ -176,7 +171,6 @@
897
898 integer(kind=c_int) :: storage_disk_has_value
899 integer(kind=c_int) :: storage_disk_is_checkpoint
900- character(kind=c_char), dimension(ADJ_NAME_LEN) :: storage_disk_filename
901 end type adj_storage_data
902
903 type, bind(c) :: adj_dictionary
904@@ -245,17 +239,22 @@
905 type(adj_vector), intent(inout) :: x
906 end subroutine adj_vec_set_random
907
908- subroutine adj_vec_to_file(x, filename) bind(c)
909+ subroutine adj_vec_write(var, x) bind(c)
910 use libadjoint_data_structures
911+ type(adj_variable), intent(in), value :: var
912 type(adj_vector), intent(in), value :: x
913- character(kind=c_char), dimension(ADJ_NAME_LEN), intent(in) :: filename
914- end subroutine adj_vec_to_file
915+ end subroutine adj_vec_write
916
917- subroutine adj_vec_from_file(x, filename) bind(c)
918+ subroutine adj_vec_read(var, x) bind(c)
919 use libadjoint_data_structures
920+ type(adj_variable), intent(in), value :: var
921 type(adj_vector), intent(out) :: x
922- character(kind=c_char), dimension(ADJ_NAME_LEN), intent(in) :: filename
923- end subroutine adj_vec_from_file
924+ end subroutine adj_vec_read
925+
926+ subroutine adj_vec_delete(var) bind(c)
927+ use libadjoint_data_structures
928+ type(adj_variable), intent(in), value :: var
929+ end subroutine adj_vec_delete
930
931 subroutine adj_mat_duplicate_proc(matin, matout) bind(c)
932 ! Allocate a new matrix, using a given matrix as the model
933
934=== modified file 'src/adj_petsc_data_structures.c'
935--- src/adj_petsc_data_structures.c 2011-11-10 21:04:41 +0000
936+++ src/adj_petsc_data_structures.c 2012-01-18 15:51:24 +0000
937@@ -21,9 +21,11 @@
938 adj_chkierr(ierr);
939 ierr = adj_register_data_callback(adjointer, ADJ_VEC_DOT_PRODUCT_CB,(void (*)(void)) petsc_vec_dot_product_proc);
940 adj_chkierr(ierr);
941- ierr = adj_register_data_callback(adjointer, ADJ_VEC_TO_FILE_CB,(void (*)(void)) petsc_vec_to_file_proc);
942- adj_chkierr(ierr);
943- ierr = adj_register_data_callback(adjointer, ADJ_VEC_FROM_FILE_CB,(void (*)(void)) petsc_vec_from_file_proc);
944+ ierr = adj_register_data_callback(adjointer, ADJ_VEC_WRITE_CB,(void (*)(void)) petsc_vec_write_proc);
945+ adj_chkierr(ierr);
946+ ierr = adj_register_data_callback(adjointer, ADJ_VEC_READ_CB,(void (*)(void)) petsc_vec_read_proc);
947+ adj_chkierr(ierr);
948+ ierr = adj_register_data_callback(adjointer, ADJ_VEC_DELETE_CB,(void (*)(void)) petsc_vec_delete_proc);
949 adj_chkierr(ierr);
950 ierr = adj_register_data_callback(adjointer, ADJ_MAT_AXPY_CB,(void (*)(void)) petsc_mat_axpy_proc);
951 adj_chkierr(ierr);
952@@ -75,6 +77,24 @@
953 #endif
954 }
955
956+void petsc_vec_delete_proc(adj_variable var)
957+{
958+#ifdef HAVE_PETSC
959+ /* Generate the filename */
960+ char filename[ADJ_NAME_LEN];
961+ adj_variable_str(var, filename, ADJ_NAME_LEN);
962+ strncat(filename, ".dat", 4);
963+
964+ if (access(filename, W_OK) == -1) {
965+ char buf[ADJ_NAME_LEN];
966+ adj_variable_str(var, buf, ADJ_NAME_LEN);
967+ fprintf(stderr, "Can remove variable %s in file '%s'. File does not exist.", buf, filename);
968+ }
969+
970+ remove(filename);
971+#endif
972+}
973+
974 void petsc_vec_getnorm_proc(adj_vector x, adj_scalar* norm)
975 {
976 #ifdef HAVE_PETSC
977@@ -100,9 +120,13 @@
978 #endif
979 }
980
981-void petsc_vec_to_file_proc(adj_vector x, char* filename)
982+void petsc_vec_write_proc(adj_variable var, adj_vector x)
983 {
984 #ifdef HAVE_PETSC
985+ /* Generate the filename */
986+ char filename[ADJ_NAME_LEN];
987+ adj_variable_str(var, filename, ADJ_NAME_LEN);
988+ strncat(filename, ".dat", 4);
989
990 if (access(filename, W_OK) == 0)
991 {
992@@ -110,8 +134,8 @@
993 }
994
995 PetscViewer viewer;
996- PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_WRITE,&viewer);
997- VecView(petsc_vec_from_adj_vector(x),viewer);
998+ PetscViewerBinaryOpen(PETSC_COMM_WORLD, filename, FILE_MODE_WRITE, &viewer);
999+ VecView(petsc_vec_from_adj_vector(x), viewer);
1000 PetscViewerDestroy(viewer);
1001 #else
1002 (void) x;
1003@@ -119,13 +143,25 @@
1004 #endif
1005 }
1006
1007-void petsc_vec_from_file_proc(adj_vector *x, char* filename)
1008+void petsc_vec_read_proc(adj_variable var, adj_vector *x)
1009 {
1010 #ifdef HAVE_PETSC
1011+ /* Generate the filename */
1012+ char filename[ADJ_NAME_LEN];
1013+ adj_variable_str(var, filename, ADJ_NAME_LEN);
1014+ strncat(filename, ".dat", 4);
1015+
1016+ if (access(filename, W_OK) == -1) {
1017+ char buf[ADJ_NAME_LEN];
1018+ adj_variable_str(var, buf, ADJ_NAME_LEN);
1019+
1020+ fprintf(stderr, "Can not access variable %s in file '%s'.", buf, filename);
1021+ }
1022+
1023 Vec *vec=(Vec*) malloc(sizeof(Vec));
1024 PetscViewer viewer;
1025- PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer);
1026- VecLoad(viewer,PETSC_NULL,vec);
1027+ PetscViewerBinaryOpen(PETSC_COMM_WORLD, filename, FILE_MODE_READ, &viewer);
1028+ VecLoad(viewer, PETSC_NULL, vec);
1029 PetscViewerDestroy(viewer);
1030 *x = petsc_vec_to_adj_vector(vec);
1031 #else
1032
1033=== modified file 'src/tests/test_adj_forget_forward_equation.c'
1034--- src/tests/test_adj_forget_forward_equation.c 2011-11-28 10:38:19 +0000
1035+++ src/tests/test_adj_forget_forward_equation.c 2012-01-18 15:51:24 +0000
1036@@ -36,6 +36,7 @@
1037 adj_storage_data storage;
1038 char filename_fwd[ADJ_NAME_LEN];
1039 int checkpoint_strategy[steps];
1040+ adj_variable_hash *varhash;
1041 adj_variable_data *var_data;
1042
1043 ierr = adj_create_adjointer(&adjointer);
1044@@ -144,13 +145,11 @@
1045 }
1046
1047 /* Besides checkpoints, no variables should be stored anymore ... */
1048- var_data=adjointer.vardata.firstnode;
1049- while(var_data!=NULL)
1050+ for(varhash=adjointer.varhash; varhash != NULL; varhash=varhash->hh.next)
1051 {
1052+ var_data = varhash->data;
1053 adj_test_assert(var_data->storage.storage_memory_has_value==var_data->storage.storage_memory_is_checkpoint, "Should have worked");
1054 adj_test_assert(var_data->storage.storage_disk_has_value==var_data->storage.storage_disk_is_checkpoint, "Should have worked");
1055-
1056- var_data=var_data->next;
1057 }
1058
1059 }
1060
1061=== modified file 'src/tests/test_checkpoint_revolve_multistage.c'
1062--- src/tests/test_checkpoint_revolve_multistage.c 2011-11-28 10:38:19 +0000
1063+++ src/tests/test_checkpoint_revolve_multistage.c 2012-01-18 15:51:24 +0000
1064@@ -552,6 +552,7 @@
1065 int ierr, i, nb_matched_variables, found_match;
1066 int duplicates=0; /* Number of variables that are recorded on both disk and memory */
1067 adj_variable var;
1068+ adj_variable_hash *varhash;
1069 adj_variable_data* data_ptr;
1070 char var_name[ADJ_NAME_LEN];
1071
1072@@ -560,20 +561,15 @@
1073 * If the variable name matches with a variable name in the expectation list,
1074 * we check if the the storage and checkpoint type match.
1075 */
1076- data_ptr=adjointer->vardata.firstnode;
1077- while (data_ptr!=NULL)
1078+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
1079 {
1080+ data_ptr=varhash->data;
1081 if (data_ptr->equation<0) /* Ignore adjoint variables */
1082- {
1083- data_ptr=data_ptr->next;
1084 continue;
1085- }
1086+
1087 if ((data_ptr->storage.storage_memory_has_value!=ADJ_TRUE) &&
1088 (data_ptr->storage.storage_disk_has_value!=ADJ_TRUE)) /* Ignore variables that are not recorded */
1089- {
1090- data_ptr=data_ptr->next;
1091 continue;
1092- }
1093
1094 var = adjointer->equations[data_ptr->equation].variable;
1095 ierr = adj_variable_str(var, var_name, ADJ_NAME_LEN);
1096@@ -640,7 +636,6 @@
1097 return ADJ_ERR_NEED_VALUE;
1098 }
1099
1100- data_ptr=data_ptr->next;
1101 }
1102
1103 /* At this point we know that the recorded variables is a subset of
1104@@ -648,23 +643,19 @@
1105 * expected variables equal, from which we now that both sets are
1106 * equivalent.
1107 */
1108- data_ptr=adjointer->vardata.firstnode;
1109 nb_matched_variables=0; /* Number of checkpoint variables in adjointer */
1110
1111- while (data_ptr!=NULL)
1112+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
1113 {
1114- if (data_ptr->equation<0) /* Ignore adjoint variables */
1115- {
1116- data_ptr=data_ptr->next;
1117+ data_ptr=varhash->data;
1118+ if (data_ptr->equation<0) /* Ignore adjoint variables */
1119 continue;
1120- }
1121
1122 if (data_ptr->storage.storage_memory_has_value)
1123 nb_matched_variables++;
1124 if (data_ptr->storage.storage_disk_has_value)
1125 nb_matched_variables++;
1126
1127- data_ptr=data_ptr->next;
1128 }
1129
1130 /* We expect the number of expected and recorded variables to be the same */
1131
1132=== modified file 'src/tests/test_checkpoint_revolve_offline.c'
1133--- src/tests/test_checkpoint_revolve_offline.c 2011-11-28 10:38:19 +0000
1134+++ src/tests/test_checkpoint_revolve_offline.c 2012-01-18 15:51:24 +0000
1135@@ -489,6 +489,7 @@
1136 int ierr, i, nb_matched_variables, found_match;
1137 int duplicates=0; /* Number of variables that are recorded on both disk and memory */
1138 adj_variable var;
1139+ adj_variable_hash *varhash;
1140 adj_variable_data* data_ptr;
1141 char var_name[ADJ_NAME_LEN];
1142
1143@@ -497,20 +498,15 @@
1144 * If the variable name matches with a variable name in the expectation list,
1145 * we check if the the storage and checkpoint type match.
1146 */
1147- data_ptr=adjointer->vardata.firstnode;
1148- while (data_ptr!=NULL)
1149+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
1150 {
1151+ data_ptr=varhash->data;
1152 if (data_ptr->equation<0) /* Ignore adjoint variables */
1153- {
1154- data_ptr=data_ptr->next;
1155 continue;
1156- }
1157+
1158 if ((data_ptr->storage.storage_memory_has_value!=ADJ_TRUE) &&
1159 (data_ptr->storage.storage_disk_has_value!=ADJ_TRUE)) /* Ignore variables that are not recorded */
1160- {
1161- data_ptr=data_ptr->next;
1162 continue;
1163- }
1164
1165 var = adjointer->equations[data_ptr->equation].variable;
1166 ierr = adj_variable_str(var, var_name, ADJ_NAME_LEN);
1167@@ -577,7 +573,6 @@
1168 return ADJ_ERR_NEED_VALUE;
1169 }
1170
1171- data_ptr=data_ptr->next;
1172 }
1173
1174 /* At this point we know that the recorded variables is a subset of
1175@@ -585,23 +580,19 @@
1176 * expected variables equal, from which we now that both sets are
1177 * equivalent.
1178 */
1179- data_ptr=adjointer->vardata.firstnode;
1180 nb_matched_variables=0; /* Number of checkpoint variables in adjointer */
1181
1182- while (data_ptr!=NULL)
1183+ for(varhash=adjointer->varhash; varhash != NULL; varhash=varhash->hh.next)
1184 {
1185+ data_ptr=varhash->data;
1186 if (data_ptr->equation<0) /* Ignore adjoint variables */
1187- {
1188- data_ptr=data_ptr->next;
1189 continue;
1190- }
1191
1192 if (data_ptr->storage.storage_memory_has_value)
1193 nb_matched_variables++;
1194 if (data_ptr->storage.storage_disk_has_value)
1195 nb_matched_variables++;
1196
1197- data_ptr=data_ptr->next;
1198 }
1199
1200 /* We expect the number of expected and recorded variables to be the same */

Subscribers

People subscribed via source and target branches