vendor/scs/src/rw.c in scs-0.4.0 vs vendor/scs/src/rw.c in scs-0.4.1

- old
+ new

@@ -1,16 +1,36 @@ #include "rw.h" +#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include "linalg.h" #include "scs.h" #include "scs_matrix.h" #include "util.h" +#if NO_READ_WRITE > 0 /* Disables all read / write functionality */ + +void SCS(write_data)(const ScsData *d, const ScsCone *k, + const ScsSettings *stgs) { + /* Do nothing */ +} +scs_int SCS(read_data)(const char *filename, ScsData **d, ScsCone **k, + ScsSettings **stgs) { + /* Failure */ + return -1; +} +void SCS(log_data_to_csv)(const ScsCone *k, const ScsSettings *stgs, + const ScsWork *w, scs_int iter, + SCS(timer) * solve_timer) { + /* Do nothing */ +} + +#else + /* writes/reads problem data to/from filename */ /* This is a VERY naive implementation, doesn't care about portability etc */ static void write_scs_cone(const ScsCone *k, FILE *fout) { fwrite(&(k->z), sizeof(scs_int), 1, fout); @@ -26,34 +46,65 @@ fwrite(&(k->ed), sizeof(scs_int), 1, fout); fwrite(&(k->psize), sizeof(scs_int), 1, fout); fwrite(k->p, sizeof(scs_float), k->psize, fout); } -static ScsCone *read_scs_cone(FILE *fin) { +/* + * Read integer data from file. If the integer width on file is + * different to scs_int then it will cast the ints after reading + * to be compatible with the SCS data types. + */ +static size_t read_int(scs_int *dest, size_t file_int_sz, size_t nitems, + FILE *fin) { + if (file_int_sz == sizeof(scs_int)) { + return fread(dest, sizeof(scs_int), nitems, fin); + } + void *ptr = scs_calloc(nitems, file_int_sz); + size_t val = fread(ptr, file_int_sz, nitems, fin); + scs_int i; + switch (file_int_sz) { + case 4: + for (i = 0; i < nitems; ++i) { + dest[i] = (scs_int)(((int *)ptr)[i]); + } + break; + case 8: + for (i = 0; i < nitems; ++i) { + dest[i] = (scs_int)(((long long *)ptr)[i]); + } + break; + } + if (ptr) { + scs_free(ptr); + } + return val; +} + +static ScsCone *read_scs_cone(FILE *fin, size_t file_int_sz) { ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone)); - fread(&(k->z), sizeof(scs_int), 1, fin); - fread(&(k->l), sizeof(scs_int), 1, fin); - fread(&(k->bsize), sizeof(scs_int), 1, fin); + read_int(&(k->z), file_int_sz, 1, fin); + read_int(&(k->l), file_int_sz, 1, fin); + read_int(&(k->bsize), file_int_sz, 1, fin); if (k->bsize > 1) { k->bl = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float)); k->bu = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float)); fread(k->bl, sizeof(scs_float), MAX(k->bsize - 1, 0), fin); fread(k->bu, sizeof(scs_float), MAX(k->bsize - 1, 0), fin); } - fread(&(k->qsize), sizeof(scs_int), 1, fin); + read_int(&(k->qsize), file_int_sz, 1, fin); if (k->qsize) { k->q = (scs_int *)scs_calloc(k->qsize, sizeof(scs_int)); - fread(k->q, sizeof(scs_int), k->qsize, fin); + read_int(k->q, file_int_sz, k->qsize, fin); } - fread(&(k->ssize), sizeof(scs_int), 1, fin); + read_int(&(k->ssize), file_int_sz, 1, fin); if (k->ssize) { k->s = (scs_int *)scs_calloc(k->ssize, sizeof(scs_int)); - fread(k->s, sizeof(scs_int), k->ssize, fin); + read_int(k->s, file_int_sz, k->ssize, fin); } - fread(&(k->ep), sizeof(scs_int), 1, fin); - fread(&(k->ed), sizeof(scs_int), 1, fin); - fread(&(k->psize), sizeof(scs_int), 1, fin); + read_int(&(k->ep), file_int_sz, 1, fin); + read_int(&(k->ed), file_int_sz, 1, fin); + read_int(&(k->psize), file_int_sz, 1, fin); if (k->psize) { k->p = (scs_float *)scs_calloc(k->psize, sizeof(scs_float)); fread(k->p, sizeof(scs_float), k->psize, fin); } return k; @@ -77,25 +128,25 @@ fwrite(&(s->adaptive_scale), sizeof(scs_int), 1, fout); /* Do not write the write_data_filename */ /* Do not write the log_csv_filename */ } -static ScsSettings *read_scs_stgs(FILE *fin) { +static ScsSettings *read_scs_stgs(FILE *fin, size_t file_int_sz) { ScsSettings *s = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings)); - fread(&(s->normalize), sizeof(scs_int), 1, fin); + read_int(&(s->normalize), file_int_sz, 1, fin); fread(&(s->scale), sizeof(scs_float), 1, fin); fread(&(s->rho_x), sizeof(scs_float), 1, fin); - fread(&(s->max_iters), sizeof(scs_int), 1, fin); + read_int(&(s->max_iters), file_int_sz, 1, fin); fread(&(s->eps_abs), sizeof(scs_float), 1, fin); fread(&(s->eps_rel), sizeof(scs_float), 1, fin); fread(&(s->eps_infeas), sizeof(scs_float), 1, fin); fread(&(s->alpha), sizeof(scs_float), 1, fin); - fread(&(s->verbose), sizeof(scs_int), 1, fin); - fread(&(s->warm_start), sizeof(scs_int), 1, fin); - fread(&(s->acceleration_lookback), sizeof(scs_int), 1, fin); - fread(&(s->acceleration_interval), sizeof(scs_int), 1, fin); - fread(&(s->adaptive_scale), sizeof(scs_int), 1, fin); + read_int(&(s->verbose), file_int_sz, 1, fin); + read_int(&(s->warm_start), file_int_sz, 1, fin); + read_int(&(s->acceleration_lookback), file_int_sz, 1, fin); + read_int(&(s->acceleration_interval), file_int_sz, 1, fin); + read_int(&(s->adaptive_scale), file_int_sz, 1, fin); return s; } static void write_amatrix(const ScsMatrix *A, FILE *fout) { scs_int Anz = A->p[A->n]; @@ -104,22 +155,22 @@ fwrite(A->p, sizeof(scs_int), A->n + 1, fout); fwrite(A->x, sizeof(scs_float), Anz, fout); fwrite(A->i, sizeof(scs_int), Anz, fout); } -static ScsMatrix *read_amatrix(FILE *fin) { +static ScsMatrix *read_amatrix(FILE *fin, size_t file_int_sz) { scs_int Anz; ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix)); - fread(&(A->m), sizeof(scs_int), 1, fin); - fread(&(A->n), sizeof(scs_int), 1, fin); + read_int(&(A->m), file_int_sz, 1, fin); + read_int(&(A->n), file_int_sz, 1, fin); A->p = (scs_int *)scs_calloc(A->n + 1, sizeof(scs_int)); - fread(A->p, sizeof(scs_int), A->n + 1, fin); + read_int(A->p, file_int_sz, A->n + 1, fin); Anz = A->p[A->n]; A->x = (scs_float *)scs_calloc(Anz, sizeof(scs_float)); A->i = (scs_int *)scs_calloc(Anz, sizeof(scs_int)); fread(A->x, sizeof(scs_float), Anz, fin); - fread(A->i, sizeof(scs_int), Anz, fin); + read_int(A->i, file_int_sz, Anz, fin); return A; } static void write_scs_data(const ScsData *d, FILE *fout) { scs_int has_p = d->P ? 1 : 0; @@ -133,34 +184,34 @@ if (d->P) { write_amatrix(d->P, fout); } } -static ScsData *read_scs_data(FILE *fin) { +static ScsData *read_scs_data(FILE *fin, size_t file_int_sz) { scs_int has_p = 0; ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData)); - fread(&(d->m), sizeof(scs_int), 1, fin); - fread(&(d->n), sizeof(scs_int), 1, fin); + + read_int(&(d->m), file_int_sz, 1, fin); + read_int(&(d->n), file_int_sz, 1, fin); d->b = (scs_float *)scs_calloc(d->m, sizeof(scs_float)); d->c = (scs_float *)scs_calloc(d->n, sizeof(scs_float)); fread(d->b, sizeof(scs_float), d->m, fin); fread(d->c, sizeof(scs_float), d->n, fin); - d->A = read_amatrix(fin); + d->A = read_amatrix(fin, file_int_sz); /* If has_p bit is not set or this hits end of file then has_p = 0 */ - has_p &= fread(&has_p, sizeof(scs_int), 1, fin); - d->P = has_p ? read_amatrix(fin) : SCS_NULL; + has_p &= read_int(&has_p, file_int_sz, 1, fin); + d->P = has_p ? read_amatrix(fin, file_int_sz) : SCS_NULL; return d; } void SCS(write_data)(const ScsData *d, const ScsCone *k, const ScsSettings *stgs) { FILE *fout = fopen(stgs->write_data_filename, "wb"); uint32_t scs_int_sz = (uint32_t)sizeof(scs_int); uint32_t scs_float_sz = (uint32_t)sizeof(scs_float); const char *scs_version = SCS_VERSION; uint32_t scs_version_sz = (uint32_t)strlen(scs_version); - scs_printf("writing data to %s\n", stgs->write_data_filename); fwrite(&(scs_int_sz), sizeof(uint32_t), 1, fout); fwrite(&(scs_float_sz), sizeof(uint32_t), 1, fout); fwrite(&(scs_version_sz), sizeof(uint32_t), 1, fout); fwrite(scs_version, 1, scs_version_sz, fout); write_scs_cone(k, fout); @@ -173,25 +224,26 @@ ScsSettings **stgs) { uint32_t file_int_sz; uint32_t file_float_sz; uint32_t file_version_sz; char file_version[16]; + errno = 0; FILE *fin = fopen(filename, "rb"); if (!fin) { scs_printf("Error reading file %s\n", filename); + scs_printf("errno:%i:%s\n", errno, strerror(errno)); return -1; } scs_printf("Reading data from %s\n", filename); fread(&(file_int_sz), sizeof(uint32_t), 1, fin); fread(&(file_float_sz), sizeof(uint32_t), 1, fin); if (file_int_sz != (uint32_t)sizeof(scs_int)) { scs_printf( - "Error, sizeof(file int) is %lu, but scs expects sizeof(int) %lu, " - "scs should be recompiled with correct flags.\n", + "Warning, sizeof(file int) is %lu, but scs expects sizeof(int) %lu. " + "SCS will attempt to cast the data, which may be slow. " + "This message can be avoided by recompiling with the correct flags.\n", (unsigned long)file_int_sz, (unsigned long)sizeof(scs_int)); - fclose(fin); - return -1; } if (file_float_sz != (uint32_t)sizeof(scs_float)) { scs_printf( "Error, sizeof(file float) is %lu, but scs expects sizeof(float) %lu, " "scs should be recompiled with the correct flags.\n", @@ -207,13 +259,14 @@ "Warning: SCS file version %s, this is SCS version %s.\n" "The file reading / writing logic might have changed.\n" "************************************************************\n", file_version, SCS_VERSION); } - *k = read_scs_cone(fin); - *d = read_scs_data(fin); - *stgs = read_scs_stgs(fin); + *k = read_scs_cone(fin, file_int_sz); + *d = read_scs_data(fin, file_int_sz); + *stgs = read_scs_stgs(fin, file_int_sz); + scs_printf("Finished reading data.\n"); fclose(fin); return 0; } void SCS(log_data_to_csv)(const ScsCone *k, const ScsSettings *stgs, @@ -346,5 +399,7 @@ fprintf(fout, "%li,", (long)w->rejected_accel_steps); fprintf(fout, "%.16e,", SCS(tocq)(solve_timer) / 1e3); fprintf(fout, "\n"); fclose(fout); } + +#endif