18 #define N sizeof(double)
19 static double byteswap(
double x)
23 #define SWAP1(i) if(N>2*(i)+1) t=buf[i],buf[i]=buf[N-1-(i)],buf[N-1-(i)]=t
24 #define SWAP2(i) SWAP1(i); SWAP1((i)+0x01); SWAP1((i)+0x02); SWAP1((i)+0x03)
25 #define SWAP3(i) SWAP2(i); SWAP2((i)+0x04); SWAP2((i)+0x08); SWAP2((i)+0x0c)
26 #define SWAP4(i) SWAP3(i); SWAP3((i)+0x10); SWAP3((i)+0x20); SWAP3((i)+0x30)
49 static int rfread(
void *ptr,
size_t n, FILE *
const fptr)
51 size_t na;
char *p=ptr;
52 while(n && (na=fread (p,1,n,fptr))) n-=na, p+=na;
56 static int rfwrite(FILE *
const fptr,
const void *ptr,
size_t n)
58 size_t na;
const char *p=ptr;
59 while(n && (na=fwrite(p,1,n,fptr))) n-=na, p+=na;
64 static struct file dopen(const char *filename,
const char mode,
int *code)
66 const double magic = 3.14159;
69 f.
fptr = fopen(filename,mode==
'r'?
"r":
"w");
72 diagnostic(
"ERROR ",__FILE__,__LINE__,
73 "AMG: could not open %s for %s",
74 filename,mode==
'r'?
"reading":
"writing");
79 if(rfread(&t,
sizeof(
double), f.fptr)){
80 diagnostic(
"ERROR ",__FILE__,__LINE__,
81 "AMG: could not read from %s",filename);
85 if(fabs(t-magic)>0.000001) {
87 if(fabs(t-magic)>0.000001) {
88 diagnostic(
"ERROR ",__FILE__,__LINE__,
89 "AMG: magic number for endian test not found in %s",
97 if(rfwrite(f.fptr, &magic,
sizeof(
double))){
98 diagnostic(
"ERROR ",__FILE__,__LINE__,
99 "AMG: could not write to %s",filename);
107 static void dread(
double *p,
size_t n,
const struct file f,
int *code)
109 if(rfread(p,n*
sizeof(
double),f.
fptr)) {
110 diagnostic(
"ERROR ",__FILE__,__LINE__,
111 "AMG: failed reading %u doubles from disk",(
unsigned)n);
115 if(f.
swap)
while(n) *p=byteswap(*p), ++p, --n;
118 static void dwrite(
const struct file f,
const double *p,
size_t n,
int *code)
120 if(rfwrite(f.
fptr, p,n*
sizeof(
double))) {
121 diagnostic(
"ERROR ",__FILE__,__LINE__,
122 "AMG: failed writing %u doubles to disk",(
unsigned)n);
127 static void dclose(
const struct file f)
133 static void dread_mpi(
double *buf, uint n,
const struct sfile f,
int *code)
139 if(MPI_File_read_all(fh,buf,count,MPI_DOUBLE,&status)) {
140 diagnostic(
"ERROR ",__FILE__,__LINE__,
141 "AMG: failed reading %u doubles from disk",(
unsigned)count);
145 if(f.swap)
while(count) *buf=byteswap(*buf), ++buf, --count;
148 static struct sfile dopen_mpi(const char *filename,
const char mode,
149 const struct comm *c,
int *code)
151 const double magic = 3.14159;
153 struct sfile f={0,0};
156 int amode = mode==
'r' ? MPI_MODE_RDONLY : MPI_MODE_CREATE|MPI_MODE_WRONLY;
157 MPI_File_open(c->c,filename,amode,MPI_INFO_NULL,&fh);
162 diagnostic(
"ERROR ",__FILE__,__LINE__,
163 "AMG: could not open %s for %s",
164 filename,mode==
'r'?
"reading":
"writing");
170 dread_mpi(&t, 1, f, code);
172 diagnostic(
"ERROR ",__FILE__,__LINE__,
173 "AMG: could not read from %s",filename);
176 if(fabs(t-magic)>0.000001) {
178 if(fabs(t-magic)>0.000001) {
179 diagnostic(
"ERROR ",__FILE__,__LINE__,
180 "AMG: magic number for endian test not found in %s",
190 diagnostic(
"ERROR ",__FILE__,__LINE__,
191 "AMG: could not write to %s",filename);
198 static void dview_mpi(ulong n,
const struct sfile f,
int *code)
202 MPI_Offset disp=n*
sizeof(double);
204 if(MPI_File_set_view(fh,disp,MPI_DOUBLE,MPI_DOUBLE,
"native",MPI_INFO_NULL)) {
205 diagnostic(
"ERROR ",__FILE__,__LINE__,
206 "AMG: failed chaning view to %u doubles",(
unsigned)n);
212 static void dclose_mpi(
const struct sfile f)
subroutine swap(b, ind, n, temp)