abl
crs_amg_io.h
Go to the documentation of this file.
1 /*==========================================================================
2 
3  File I/O for AMG
4  small wrappers to read/write files consisting of doubles
5 
6  ==========================================================================*/
7 
8 #ifndef MPI
9 #undef USEMPIIO
10 #endif
11 
12 #ifdef NOMPIIO
13 #undef USEMPIIO
14 #endif
15 
16 /* reverse the byte order of the given double
17  portable up to 129-byte doubles, standards conforming */
18 #define N sizeof(double)
19 static double byteswap(double x)
20 {
21  char t, buf[N];
22  memcpy(buf,&x,N);
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)
27  SWAP4(0);
28 #undef SWAP1
29 #undef SWAP2
30 #undef SWAP3
31 #undef SWAP4
32  memcpy(&x,buf,N);
33  return x;
34 }
35 #undef N
36 
37 struct file {
38  FILE *fptr;
39  int swap;
40 };
41 
42 #ifdef USEMPIIO
43 struct sfile {
44  MPI_File fh;
45  int swap;
46 };
47 #endif
48 
49 static int rfread(void *ptr, size_t n, FILE *const fptr)
50 {
51  size_t na; char *p=ptr;
52  while(n && (na=fread (p,1,n,fptr))) n-=na, p+=na;
53  return n!=0;
54 }
55 
56 static int rfwrite(FILE *const fptr, const void *ptr, size_t n)
57 {
58  size_t na; const char *p=ptr;
59  while(n && (na=fwrite(p,1,n,fptr))) n-=na, p+=na;
60  return n!=0;
61 }
62 
63 
64 static struct file dopen(const char *filename, const char mode,int *code)
65 {
66  const double magic = 3.14159;
67  double t;
68  struct file f;
69  f.fptr = fopen(filename,mode=='r'?"r":"w");
70  f.swap = 0;
71  if(f.fptr==0) {
72  diagnostic("ERROR ",__FILE__,__LINE__,
73  "AMG: could not open %s for %s",
74  filename,mode=='r'?"reading":"writing");
75  *code=1;
76  return f;
77  }
78  if(mode=='r') {
79  if(rfread(&t,sizeof(double), f.fptr)){
80  diagnostic("ERROR ",__FILE__,__LINE__,
81  "AMG: could not read from %s",filename);
82  *code=1;
83  return f;
84  }
85  if(fabs(t-magic)>0.000001) {
86  t=byteswap(t);
87  if(fabs(t-magic)>0.000001) {
88  diagnostic("ERROR ",__FILE__,__LINE__,
89  "AMG: magic number for endian test not found in %s",
90  filename);
91  *code=1;
92  return f;
93  }
94  f.swap = 1;
95  }
96  } else {
97  if(rfwrite(f.fptr, &magic,sizeof(double))){
98  diagnostic("ERROR ",__FILE__,__LINE__,
99  "AMG: could not write to %s",filename);
100  *code=1;
101  return f;
102  }
103  }
104  return f;
105 }
106 
107 static void dread(double *p, size_t n, const struct file f,int *code)
108 {
109  if(rfread(p,n*sizeof(double),f.fptr)) {
110  diagnostic("ERROR ",__FILE__,__LINE__,
111  "AMG: failed reading %u doubles from disk",(unsigned)n);
112  *code=1;
113  return;
114  }
115  if(f.swap) while(n) *p=byteswap(*p), ++p, --n;
116 }
117 
118 static void dwrite(const struct file f, const double *p, size_t n,int *code)
119 {
120  if(rfwrite(f.fptr, p,n*sizeof(double))) {
121  diagnostic("ERROR ",__FILE__,__LINE__,
122  "AMG: failed writing %u doubles to disk",(unsigned)n);
123  *code=1;
124  }
125 }
126 
127 static void dclose(const struct file f)
128 {
129  fclose(f.fptr);
130 }
131 
132 #ifdef USEMPIIO
133 static void dread_mpi(double *buf, uint n, const struct sfile f,int *code)
134 {
135  MPI_File fh=f.fh;
136  MPI_Status status;
137  int count=n;
138 
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);
142  *code=1;
143  return;
144  }
145  if(f.swap) while(count) *buf=byteswap(*buf), ++buf, --count;
146 }
147 
148 static struct sfile dopen_mpi(const char *filename, const char mode,
149  const struct comm *c,int *code)
150 {
151  const double magic = 3.14159;
152  double t;
153  struct sfile f={0,0};
154  MPI_File fh;
155 
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);
158 
159  f.fh = fh;
160 
161  if(f.fh==0) {
162  diagnostic("ERROR ",__FILE__,__LINE__,
163  "AMG: could not open %s for %s",
164  filename,mode=='r'?"reading":"writing");
165  *code=1;
166  return f;
167  }
168 
169  if(mode=='r') {
170  dread_mpi(&t, 1, f, code);
171  if(*code!=0) {
172  diagnostic("ERROR ",__FILE__,__LINE__,
173  "AMG: could not read from %s",filename);
174  return f;
175  }
176  if(fabs(t-magic)>0.000001) {
177  t=byteswap(t);
178  if(fabs(t-magic)>0.000001) {
179  diagnostic("ERROR ",__FILE__,__LINE__,
180  "AMG: magic number for endian test not found in %s",
181  filename);
182  *code=1;
183  return f;
184  }
185  f.swap = 1;
186  }
187  } else {
188  /* dwrite_mpi(&t, 1, f.fh, code); */
189  if(*code!=0) {
190  diagnostic("ERROR ",__FILE__,__LINE__,
191  "AMG: could not write to %s",filename);
192  return f;
193  }
194  }
195  return f;
196 }
197 
198 static void dview_mpi(ulong n, const struct sfile f, int *code)
199 {
200  MPI_File fh=f.fh;
201  MPI_Info info;
202  MPI_Offset disp=n*sizeof(double);
203 
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);
207  *code=1;
208  return;
209  }
210 }
211 
212 static void dclose_mpi(const struct sfile f)
213 {
214  MPI_File fh=f.fh;
215  MPI_File_close(&fh);
216 }
217 #endif
218 
file::fptr
FILE * fptr
Definition: crs_amg_io.h:38
rid::p
uint p
Definition: crs_amg.c:231
find_id_work::p
uint p
Definition: crs_amg.c:652
swap
subroutine swap(b, ind, n, temp)
Definition: navier7.f:504
BUILD_LIST
#define BUILD_LIST(k)
N
#define N
Definition: crs_amg_io.h:18
rid
Definition: crs_amg.c:231
labelled_rid::rid
struct rid rid
Definition: crs_amg.c:1145
crs_data::Q_Aff
struct Q * Q_Aff
Definition: crs_amg.c:122
crs_data::timing_n
uint timing_n
Definition: crs_amg.c:125
find_id_data::cr
struct crystal * cr
Definition: crs_amg.c:625
crs_free
#define crs_free
Definition: crs_amg.c:13
file
Definition: crs_amg_io.h:37
crs_data::buf
double * buf
Definition: crs_amg.c:124
row_distr
@ row_distr
Definition: crs_amg.c:1085
gnz::j
ulong j
Definition: crs_amg.c:241
find_id_map
Definition: crs_amg.c:620
crs_data::tni
double tni
Definition: crs_amg.c:115
crs_data::c_old
double * c_old
Definition: crs_amg.c:124
find_id_data
Definition: crs_amg.c:622
rnz::j
struct rid i j
Definition: crs_amg.c:1091
crs_solve
#define crs_solve
Definition: crs_amg.c:11
crs_data::W
struct csr_mat * W
Definition: crs_amg.c:123
rid_equal
#define rid_equal(a, b)
Definition: crs_amg.c:1087
csr_mat::cn
uint cn
Definition: crs_amg.c:43
csr_mat::row_off
uint * row_off
Definition: crs_amg.c:43
gnz
Definition: crs_amg.c:241
rnz
Definition: crs_amg.c:1090
crs_data::r
double * r
Definition: crs_amg.c:124
crs_data::umap
uint * umap
Definition: crs_amg.c:114
crs_data
Definition: crs_amg.c:111
Q::nloc
uint nloc
Definition: crs_amg.c:80
csr_mat::rn
uint rn
Definition: crs_amg.c:43
gnz::a
double a
Definition: crs_amg.c:241
Q::gsh
struct gs_data * gsh
Definition: crs_amg.c:80
crs_data::lvl_offset
uint * lvl_offset
Definition: crs_amg.c:120
crs_data::cheb_rho
double * cheb_rho
Definition: crs_amg.c:119
crs_amg_io.h
crs_data::comm
struct comm comm
Definition: crs_amg.c:112
id_data::D
double D
Definition: crs_amg.c:235
labelled_rid::id
ulong id
Definition: crs_amg.c:1145
find_id_work::id
ulong id
Definition: crs_amg.c:652
crs_data::AfP
struct csr_mat * AfP
Definition: crs_amg.c:123
rnz::v
double v
Definition: crs_amg.c:1091
crs_data::cheb_m
unsigned * cheb_m
Definition: crs_amg.c:118
csr_mat::n
uint n
Definition: crs_xxt.c:204
mat_order
mat_order
Definition: crs_amg.c:1084
crs_data::Aff
struct csr_mat * Aff
Definition: crs_amg.c:123
find_id_data::work
struct array work
Definition: crs_amg.c:624
find_id_work::wp
uint wp
Definition: crs_amg.c:652
crs_data::Dff
double * Dff
Definition: crs_amg.c:121
file::swap
int swap
Definition: crs_amg_io.h:39
crs_data::null_space
int null_space
Definition: crs_amg.c:116
crs_data::b
double * b
Definition: crs_amg.c:124
crs_data::x
double * x
Definition: crs_amg.c:124
crs_setup
#define crs_setup
Definition: crs_amg.c:10
find_id_map::p
uint p
Definition: crs_amg.c:620
col_distr
@ col_distr
Definition: crs_amg.c:1085
csr_mat
Definition: crs_amg.c:42
distr
distr
Definition: crs_amg.c:1085
id_data::level
unsigned level
Definition: crs_amg.c:237
id_data
Definition: crs_amg.c:234
nz_pos_equal
#define nz_pos_equal(a, b)
Definition: crs_amg.c:1093
AMG_BLOCK_ROWS
#define AMG_BLOCK_ROWS
Definition: crs_amg.c:16
crs_data::Q_AfP
struct Q * Q_AfP
Definition: crs_amg.c:122
crs_data::gs_top
struct gs_data * gs_top
Definition: crs_amg.c:113
crs_data::levels
unsigned levels
Definition: crs_amg.c:117
csr_mat::col
uint * col
Definition: crs_amg.c:43
find_id_work
Definition: crs_amg.c:652
find_id_map::id
ulong id
Definition: crs_amg.c:620
crs_data::un
uint un
Definition: crs_amg.c:114
rid::i
uint i
Definition: crs_amg.c:231
col_major
@ col_major
Definition: crs_amg.c:1084
gnz::i
ulong i
Definition: crs_amg.c:241
id_data::id
ulong id
Definition: crs_amg.c:236
crs_stats
#define crs_stats
Definition: crs_amg.c:12
row_major
@ row_major
Definition: crs_amg.c:1084
SWAP4
#define SWAP4(i)
csr_mat::a
double * a
Definition: crs_amg.c:44
crs_data::timing
double * timing
Definition: crs_amg.c:125
AMG_MAX_ROWS
#define AMG_MAX_ROWS
Definition: crs_amg.c:20
Q
Definition: crs_amg.c:80
crs_data::Q_W
struct Q * Q_W
Definition: crs_amg.c:122
crs_data::c
double * c
Definition: crs_amg.c:124
labelled_rid
Definition: crs_amg.c:1144
find_id_data::map
struct array map
Definition: crs_amg.c:623