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