1 #include "rw.h"
2
3 #include <stdint.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "linalg.h"
8 #include "scs.h"
9 #include "scs_matrix.h"
10 #include "util.h"
11
12 /* writes/reads problem data to/from filename */
13 /* This is a VERY naive implementation, doesn't care about portability etc */
14
write_scs_cone(const ScsCone * k,FILE * fout)15 static void write_scs_cone(const ScsCone *k, FILE *fout) {
16 fwrite(&(k->z), sizeof(scs_int), 1, fout);
17 fwrite(&(k->l), sizeof(scs_int), 1, fout);
18 fwrite(&(k->bsize), sizeof(scs_int), 1, fout);
19 fwrite(k->bl, sizeof(scs_float), MAX(k->bsize - 1, 0), fout);
20 fwrite(k->bu, sizeof(scs_float), MAX(k->bsize - 1, 0), fout);
21 fwrite(&(k->qsize), sizeof(scs_int), 1, fout);
22 fwrite(k->q, sizeof(scs_int), k->qsize, fout);
23 fwrite(&(k->ssize), sizeof(scs_int), 1, fout);
24 fwrite(k->s, sizeof(scs_int), k->ssize, fout);
25 fwrite(&(k->ep), sizeof(scs_int), 1, fout);
26 fwrite(&(k->ed), sizeof(scs_int), 1, fout);
27 fwrite(&(k->psize), sizeof(scs_int), 1, fout);
28 fwrite(k->p, sizeof(scs_float), k->psize, fout);
29 }
30
read_scs_cone(FILE * fin)31 static ScsCone *read_scs_cone(FILE *fin) {
32 ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
33 fread(&(k->z), sizeof(scs_int), 1, fin);
34 fread(&(k->l), sizeof(scs_int), 1, fin);
35 fread(&(k->bsize), sizeof(scs_int), 1, fin);
36 k->bl = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
37 k->bu = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
38 fread(k->bl, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
39 fread(k->bu, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
40 fread(&(k->qsize), sizeof(scs_int), 1, fin);
41 k->q = (scs_int *)scs_calloc(k->qsize, sizeof(scs_int));
42 fread(k->q, sizeof(scs_int), k->qsize, fin);
43 fread(&(k->ssize), sizeof(scs_int), 1, fin);
44 k->s = (scs_int *)scs_calloc(k->ssize, sizeof(scs_int));
45 fread(k->s, sizeof(scs_int), k->ssize, fin);
46 fread(&(k->ep), sizeof(scs_int), 1, fin);
47 fread(&(k->ed), sizeof(scs_int), 1, fin);
48 fread(&(k->psize), sizeof(scs_int), 1, fin);
49 k->p = (scs_float *)scs_calloc(k->psize, sizeof(scs_float));
50 fread(k->p, sizeof(scs_float), k->psize, fin);
51 return k;
52 }
53
write_scs_stgs(const ScsSettings * s,FILE * fout)54 static void write_scs_stgs(const ScsSettings *s, FILE *fout) {
55 /* Warm start to false for now */
56 scs_int warm_start = 0;
57 fwrite(&(s->normalize), sizeof(scs_int), 1, fout);
58 fwrite(&(s->scale), sizeof(scs_float), 1, fout);
59 fwrite(&(s->rho_x), sizeof(scs_float), 1, fout);
60 fwrite(&(s->max_iters), sizeof(scs_int), 1, fout);
61 fwrite(&(s->eps_abs), sizeof(scs_float), 1, fout);
62 fwrite(&(s->eps_rel), sizeof(scs_float), 1, fout);
63 fwrite(&(s->eps_infeas), sizeof(scs_float), 1, fout);
64 fwrite(&(s->alpha), sizeof(scs_float), 1, fout);
65 fwrite(&(s->verbose), sizeof(scs_int), 1, fout);
66 fwrite(&warm_start, sizeof(scs_int), 1, fout);
67 fwrite(&(s->acceleration_lookback), sizeof(scs_int), 1, fout);
68 fwrite(&(s->acceleration_interval), sizeof(scs_int), 1, fout);
69 fwrite(&(s->adaptive_scale), sizeof(scs_int), 1, fout);
70 /* Do not write the write_data_filename */
71 /* Do not write the log_csv_filename */
72 }
73
read_scs_stgs(FILE * fin)74 static ScsSettings *read_scs_stgs(FILE *fin) {
75 ScsSettings *s = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
76 fread(&(s->normalize), sizeof(scs_int), 1, fin);
77 fread(&(s->scale), sizeof(scs_float), 1, fin);
78 fread(&(s->rho_x), sizeof(scs_float), 1, fin);
79 fread(&(s->max_iters), sizeof(scs_int), 1, fin);
80 fread(&(s->eps_abs), sizeof(scs_float), 1, fin);
81 fread(&(s->eps_rel), sizeof(scs_float), 1, fin);
82 fread(&(s->eps_infeas), sizeof(scs_float), 1, fin);
83 fread(&(s->alpha), sizeof(scs_float), 1, fin);
84 fread(&(s->verbose), sizeof(scs_int), 1, fin);
85 fread(&(s->warm_start), sizeof(scs_int), 1, fin);
86 fread(&(s->acceleration_lookback), sizeof(scs_int), 1, fin);
87 fread(&(s->acceleration_interval), sizeof(scs_int), 1, fin);
88 fread(&(s->adaptive_scale), sizeof(scs_int), 1, fin);
89 return s;
90 }
91
write_amatrix(const ScsMatrix * A,FILE * fout)92 static void write_amatrix(const ScsMatrix *A, FILE *fout) {
93 scs_int Anz = A->p[A->n];
94 fwrite(&(A->m), sizeof(scs_int), 1, fout);
95 fwrite(&(A->n), sizeof(scs_int), 1, fout);
96 fwrite(A->p, sizeof(scs_int), A->n + 1, fout);
97 fwrite(A->x, sizeof(scs_float), Anz, fout);
98 fwrite(A->i, sizeof(scs_int), Anz, fout);
99 }
100
read_amatrix(FILE * fin)101 static ScsMatrix *read_amatrix(FILE *fin) {
102 scs_int Anz;
103 ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
104 fread(&(A->m), sizeof(scs_int), 1, fin);
105 fread(&(A->n), sizeof(scs_int), 1, fin);
106 A->p = (scs_int *)scs_calloc(A->n + 1, sizeof(scs_int));
107 fread(A->p, sizeof(scs_int), A->n + 1, fin);
108 Anz = A->p[A->n];
109 A->x = (scs_float *)scs_calloc(Anz, sizeof(scs_float));
110 A->i = (scs_int *)scs_calloc(Anz, sizeof(scs_int));
111 fread(A->x, sizeof(scs_float), Anz, fin);
112 fread(A->i, sizeof(scs_int), Anz, fin);
113 return A;
114 }
115
write_scs_data(const ScsData * d,FILE * fout)116 static void write_scs_data(const ScsData *d, FILE *fout) {
117 scs_int has_p = d->P ? 1 : 0;
118 fwrite(&(d->m), sizeof(scs_int), 1, fout);
119 fwrite(&(d->n), sizeof(scs_int), 1, fout);
120 fwrite(d->b, sizeof(scs_float), d->m, fout);
121 fwrite(d->c, sizeof(scs_float), d->n, fout);
122 write_amatrix(d->A, fout);
123 /* write has P bit */
124 fwrite(&has_p, sizeof(scs_int), 1, fout);
125 if (d->P) {
126 write_amatrix(d->P, fout);
127 }
128 }
129
read_scs_data(FILE * fin)130 static ScsData *read_scs_data(FILE *fin) {
131 scs_int has_p = 0;
132 ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
133 fread(&(d->m), sizeof(scs_int), 1, fin);
134 fread(&(d->n), sizeof(scs_int), 1, fin);
135 d->b = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
136 d->c = (scs_float *)scs_calloc(d->n, sizeof(scs_float));
137 fread(d->b, sizeof(scs_float), d->m, fin);
138 fread(d->c, sizeof(scs_float), d->n, fin);
139 d->A = read_amatrix(fin);
140 /* If has_p bit is not set or this hits end of file then has_p = 0 */
141 has_p &= fread(&has_p, sizeof(scs_int), 1, fin);
142 d->P = has_p ? read_amatrix(fin) : SCS_NULL;
143 return d;
144 }
145
SCS(write_data)146 void SCS(write_data)(const ScsData *d, const ScsCone *k,
147 const ScsSettings *stgs) {
148 FILE *fout = fopen(stgs->write_data_filename, "wb");
149 uint32_t scs_int_sz = (uint32_t)SCS(sizeof_int)();
150 uint32_t scs_float_sz = (uint32_t)SCS(sizeof_float)();
151 const char *scs_version = SCS_VERSION;
152 uint32_t scs_version_sz = (uint32_t)strlen(scs_version);
153 scs_printf("writing data to %s\n", stgs->write_data_filename);
154 fwrite(&(scs_int_sz), sizeof(uint32_t), 1, fout);
155 fwrite(&(scs_float_sz), sizeof(uint32_t), 1, fout);
156 fwrite(&(scs_version_sz), sizeof(uint32_t), 1, fout);
157 fwrite(scs_version, 1, scs_version_sz, fout);
158 write_scs_cone(k, fout);
159 write_scs_data(d, fout);
160 write_scs_stgs(stgs, fout);
161 fclose(fout);
162 }
163
SCS(read_data)164 scs_int SCS(read_data)(const char *filename, ScsData **d, ScsCone **k,
165 ScsSettings **stgs) {
166 uint32_t file_int_sz;
167 uint32_t file_float_sz;
168 uint32_t file_version_sz;
169 char file_version[16];
170 FILE *fin = fopen(filename, "rb");
171 if (!fin) {
172 scs_printf("Error reading file %s\n", filename);
173 return -1;
174 }
175 scs_printf("Reading data from %s\n", filename);
176 fread(&(file_int_sz), sizeof(uint32_t), 1, fin);
177 fread(&(file_float_sz), sizeof(uint32_t), 1, fin);
178 if (file_int_sz != (uint32_t)sizeof(scs_int)) {
179 scs_printf(
180 "Error, sizeof(file int) is %lu, but scs expects sizeof(int) %lu, "
181 "scs should be recompiled with correct flags.\n",
182 (unsigned long)file_int_sz, (unsigned long)sizeof(scs_int));
183 fclose(fin);
184 return -1;
185 }
186 if (file_float_sz != (uint32_t)sizeof(scs_float)) {
187 scs_printf(
188 "Error, sizeof(file float) is %lu, but scs expects sizeof(float) %lu, "
189 "scs should be recompiled with the correct flags.\n",
190 (unsigned long)file_float_sz, (unsigned long)sizeof(scs_float));
191 fclose(fin);
192 return -1;
193 }
194 fread(&(file_version_sz), sizeof(uint32_t), 1, fin);
195 fread(file_version, 1, file_version_sz, fin);
196 file_version[file_version_sz] = '\0';
197 if (strcmp(file_version, SCS_VERSION) != 0) {
198 scs_printf("************************************************************\n"
199 "Warning: SCS file version %s, this is SCS version %s.\n"
200 "The file reading / writing logic might have changed.\n"
201 "************************************************************\n",
202 file_version, SCS_VERSION);
203 }
204 *k = read_scs_cone(fin);
205 *d = read_scs_data(fin);
206 *stgs = read_scs_stgs(fin);
207 fclose(fin);
208 return 0;
209 }
210
SCS(log_data_to_csv)211 void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
212 const ScsSettings *stgs, const ScsWork *w,
213 scs_int iter, SCS(timer) * solve_timer) {
214 ScsResiduals *r = w->r_orig;
215 ScsResiduals *r_n = w->r_normalized;
216 /* if iter 0 open to write, else open to append */
217 FILE *fout = fopen(stgs->log_csv_filename, iter == 0 ? "w" : "a");
218 if (!fout) {
219 scs_printf("Error: Could not open %s for writing\n",
220 stgs->log_csv_filename);
221 return;
222 }
223 scs_int l = w->m + w->n + 1;
224 if (iter == 0) {
225 /* need to end in comma so that csv parsing is correct */
226 fprintf(fout, "iter,"
227 "res_pri,"
228 "res_dual,"
229 "gap,"
230 "ax_s_btau_nrm_inf,"
231 "px_aty_ctau_nrm_inf,"
232 "ax_s_btau_nrm_2,"
233 "px_aty_ctau_nrm_2,"
234 "res_infeas,"
235 "res_unbdd_a,"
236 "res_unbdd_p,"
237 "pobj,"
238 "dobj,"
239 "tau,"
240 "kap,"
241 "res_pri_normalized,"
242 "res_dual_normalized,"
243 "gap_normalized,"
244 "ax_s_btau_nrm_inf_normalized,"
245 "px_aty_ctau_nrm_inf_normalized,"
246 "ax_s_btau_nrm_2_normalized,"
247 "px_aty_ctau_nrm_2_normalized,"
248 "res_infeas_normalized,"
249 "res_unbdd_a_normalized,"
250 "res_unbdd_p_normalized,"
251 "pobj_normalized,"
252 "dobj_normalized,"
253 "tau_normalized,"
254 "kap_normalized,"
255 "scale,"
256 "diff_u_ut_nrm_2,"
257 "diff_v_v_prev_nrm_2,"
258 "diff_u_ut_nrm_inf,"
259 "diff_v_v_prev_nrm_inf,"
260 "aa_norm,"
261 "accepted_accel_steps,"
262 "rejected_accel_steps,"
263 "time,"
264 "\n");
265 }
266 fprintf(fout, "%li,", (long)iter);
267 fprintf(fout, "%.16e,", r->res_pri);
268 fprintf(fout, "%.16e,", r->res_dual);
269 fprintf(fout, "%.16e,", r->gap);
270 fprintf(fout, "%.16e,", SCS(norm_inf)(r->ax_s_btau, w->m));
271 fprintf(fout, "%.16e,", SCS(norm_inf)(r->px_aty_ctau, w->n));
272 fprintf(fout, "%.16e,", SCS(norm_2)(r->ax_s_btau, w->m));
273 fprintf(fout, "%.16e,", SCS(norm_2)(r->px_aty_ctau, w->n));
274 fprintf(fout, "%.16e,", r->res_infeas);
275 fprintf(fout, "%.16e,", r->res_unbdd_a);
276 fprintf(fout, "%.16e,", r->res_unbdd_p);
277 fprintf(fout, "%.16e,", r->pobj);
278 fprintf(fout, "%.16e,", r->dobj);
279 fprintf(fout, "%.16e,", r->tau);
280 fprintf(fout, "%.16e,", r->kap);
281 fprintf(fout, "%.16e,", r_n->res_pri);
282 fprintf(fout, "%.16e,", r_n->res_dual);
283 fprintf(fout, "%.16e,", r_n->gap);
284 fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->ax_s_btau, w->m));
285 fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->px_aty_ctau, w->n));
286 fprintf(fout, "%.16e,", SCS(norm_2)(r_n->ax_s_btau, w->m));
287 fprintf(fout, "%.16e,", SCS(norm_2)(r_n->px_aty_ctau, w->n));
288 fprintf(fout, "%.16e,", r_n->res_infeas);
289 fprintf(fout, "%.16e,", r_n->res_unbdd_a);
290 fprintf(fout, "%.16e,", r_n->res_unbdd_p);
291 fprintf(fout, "%.16e,", r_n->pobj);
292 fprintf(fout, "%.16e,", r_n->dobj);
293 fprintf(fout, "%.16e,", r_n->tau);
294 fprintf(fout, "%.16e,", r_n->kap);
295 fprintf(fout, "%.16e,", w->scale);
296 fprintf(fout, "%.16e,", SCS(norm_diff)(w->u, w->u_t, l));
297 fprintf(fout, "%.16e,", SCS(norm_diff)(w->v, w->v_prev, l));
298 fprintf(fout, "%.16e,", SCS(norm_inf_diff)(w->u, w->u_t, l));
299 fprintf(fout, "%.16e,", SCS(norm_inf_diff)(w->v, w->v_prev, l));
300 fprintf(fout, "%.16e,", w->aa_norm);
301 fprintf(fout, "%li,", (long)w->accepted_accel_steps);
302 fprintf(fout, "%li,", (long)w->rejected_accel_steps);
303 fprintf(fout, "%.16e,", SCS(tocq)(solve_timer) / 1e3);
304 fprintf(fout, "\n");
305 fclose(fout);
306 }
307