Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
graph_io_aux.cxx
Go to the documentation of this file.
1 namespace CTF_int {
5  template <typename dtype>
6  const char * get_fmt(){
7  printf("CTF ERROR: Format of tensor unsupported for sparse I/O\n");
8  IASSERT(0);
9  return NULL;
10  }
11 
12  template <>
13  inline const char * get_fmt<float>(){
14  return " %f";
15  }
16 
17  template <>
18  inline const char * get_fmt<double>(){
19  return " %lf";
20  }
21 
22  template <>
23  inline const char * get_fmt<int>(){
24  return " %d";
25  }
26 
27  template <>
28  inline const char * get_fmt<int64_t>(){
29  return " %ld";
30  }
31 
44  template <typename dtype>
45  void parse_sparse_tensor_data(char **lvals, int order, dtype const * pmulid, int * lens, int64_t nvals, CTF::Pair<dtype> * pairs, bool with_vals){
46  int64_t i;
47  dtype mulid;
48  if (!with_vals) mulid = *pmulid;
49 
50  int64_t * ind = (int64_t *)malloc(order*sizeof(int64_t));
51  for (i=0; i<nvals; i++) {
52  double v;
53  int ptr = 0;
54  int aptr;
55  sscanf(lvals[i]+ptr, "%ld%n", ind+0, &aptr);
56  ptr += aptr;
57  for (int j=1; j<order; j++){
58  sscanf(lvals[i]+ptr, " %ld%n", ind+j, &aptr);
59  ptr += aptr;
60  }
61  if (with_vals)
62  sscanf(lvals[i]+ptr, get_fmt<dtype>(), &v);
63  int64_t lda = 1;
64  pairs[i].k = 0;
65  for (int j=0; j<order; j++){
66  pairs[i].k += ind[j]*lda;
67  lda *= lens[j];
68  }
69  if (with_vals)
70  pairs[i].d = v;
71  else
72  pairs[i].d = mulid;
73  }
74  free(ind);
75  }
76 
90  template <typename dtype>
91  char * serialize_sparse_tensor_data(int order, int * lens, int64_t nvals, CTF::Pair<dtype> * pairs, bool with_vals, int64_t & str_len){
92  int64_t i;
93 
94  int64_t * ind = (int64_t *)malloc(order*sizeof(int64_t));
95  str_len = 0;
96  for (i=0; i<nvals; i++){
97  int64_t key = pairs[i].k;
98  for (int j=0; j<order; j++){
99  ind[j] = key % lens[j];
100  key = key / lens[j];
101  }
102 
103  int astr_len = 0;
104  astr_len += snprintf(NULL, 0, "%ld", ind[0]);
105  for (int j=1; j<order; j++){
106  astr_len += snprintf(NULL, 0, " %ld", ind[j]);
107  }
108  if (with_vals)
109  astr_len += snprintf(NULL, 0, get_fmt<dtype>(), pairs[i].d);
110  astr_len += snprintf(NULL, 0, "\n");
111 
112  str_len += astr_len;
113  }
114  char * datastr = (char*)CTF_int::alloc(sizeof(char)*(str_len+1));
115  int64_t str_ptr = 0;
116  for (i=0; i<nvals; i++){
117  int64_t key = pairs[i].k;
118  for (int j=0; j<order; j++){
119  ind[j] = key % lens[j];
120  key = key / lens[j];
121  }
122 
123  str_ptr += sprintf(datastr+str_ptr, "%ld", ind[0]);
124  for (int j=1; j<order; j++){
125  str_ptr += sprintf(datastr+str_ptr, " %ld", ind[j]);
126  }
127  if (with_vals)
128  str_ptr += sprintf(datastr+str_ptr, get_fmt<dtype>(), pairs[i].d);
129  str_ptr += sprintf(datastr+str_ptr, "\n");
130  }
131  free(ind);
132  return datastr;
133  }
134 
141  template <typename dtype>
142  int64_t read_data_mpiio(CTF::World const * dw, char const *fpath, char ***datastr){
143  MPI_File fh;
144  MPI_Offset filesize;
145  MPI_Offset localsize;
146  MPI_Offset start,end;
147  MPI_Status status;
148  char *chunk = NULL;
149  int overlap = 300; // define
150  int64_t ned = 0;
151  int64_t i = 0;
152 
153  MPI_File_open(MPI_COMM_WORLD,fpath, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
154 
155  /* Get the size of file */
156  MPI_File_get_size(fh, &filesize); //return in bytes
157 
158  localsize = filesize/dw->np;
159  start = dw->rank * localsize;
160  end = start + localsize;
161  end += overlap;
162 
163  if (dw->rank == dw->np-1) end = filesize;
164  localsize = end - start; //OK
165 
166  chunk = (char*)malloc( (localsize + 1)*sizeof(char));
167  MPI_File_read_at_all(fh, start, chunk, localsize, MPI_CHAR, &status);
168  chunk[localsize] = '\0';
169 
170  int64_t locstart=0, locend=localsize;
171  if (dw->rank != 0) {
172  while(chunk[locstart] != '\n') locstart++;
173  locstart++;
174  }
175  if (dw->rank != dw->np-1) {
176  locend-=overlap;
177  while(chunk[locend] != '\n') locend++;
178  locend++;
179  }
180  localsize = locend-locstart; //OK
181 
182  char *data = (char *)CTF_int::alloc((localsize+1)*sizeof(char));
183  memcpy(data, &(chunk[locstart]), localsize);
184  data[localsize] = '\0';
185  free(chunk);
186 
187  //printf("[%d] local chunk = [%ld,%ld) / %ld\n", myid, start+locstart, start+locstart+localsize, filesize);
188  for ( i=0; i<localsize; i++){
189  if (data[i] == '\n') ned++;
190  }
191  //printf("[%d] ned= %ld\n",myid, ned);
192 
193  (*datastr) = (char **)CTF_int::alloc(std::max(ned,(int64_t)1)*sizeof(char *));
194  (*datastr)[0] = strtok(data,"\n");
195 
196  for ( i=1; i < ned; i++)
197  (*datastr)[i] = strtok(NULL, "\n");
198  if ((*datastr)[0] == NULL)
199  CTF_int::cdealloc(data);
200  MPI_File_close(&fh);
201 
202  return ned;
203  }
204 
205 
213  template <typename dtype>
214  void write_data_mpiio(CTF::World const * dw, char const *fpath, char * datastr, int64_t str_len){
215  MPI_File fh;
216  MPI_Offset offset;
217  MPI_Status status;
218 
219  // clear contents of file if exists, then reopen
220  MPI_File_open(MPI_COMM_WORLD, fpath, MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh);
221  MPI_File_close(&fh);
222  MPI_File_open(MPI_COMM_WORLD, fpath, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &fh);
223 
224  int64_t ioffset;
225  MPI_Scan(&str_len, &ioffset, 1, MPI_INT64_T, MPI_SUM, dw->comm);
226 
227  offset = ioffset - str_len;
228 
229  MPI_File_write_at_all(fh, offset, datastr, str_len, MPI_CHAR, &status);
230  MPI_File_close(&fh);
231  }
232 
233 }
234 
char * serialize_sparse_tensor_data(int order, int *lens, int64_t nvals, CTF::Pair< dtype > *pairs, bool with_vals, int64_t &str_len)
serialize sparse tensor data to create string
const char * get_fmt< float >()
dtype d
tensor value associated with index
Definition: tensor.h:34
void * alloc(int64_t len)
alloc abstraction
Definition: memcontrol.cxx:365
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
int64_t k
key, global index [i1,i2,...] specified as i1+len[0]*i2+...
Definition: tensor.h:31
#define IASSERT(...)
Definition: common.h:74
index-value pair used for tensor data input
Definition: tensor.h:28
const char * get_fmt< int >()
int rank
rank of local processor
Definition: world.h:24
const char * get_fmt< double >()
void write_data_mpiio(CTF::World const *dw, char const *fpath, char *datastr, int64_t str_len)
write sparse tensor data to file using MPI-I/O, from string with one entry per line (different entrie...
int64_t read_data_mpiio(CTF::World const *dw, char const *fpath, char ***datastr)
read sparse tensor data from file using MPI-I/O, creating string with one entry per line (different e...
int cdealloc(void *ptr)
free abstraction
Definition: memcontrol.cxx:480
const char * get_fmt()
return format string for templated type
Definition: graph_io_aux.cxx:6
int64_t key
Definition: back_comp.h:66
int np
number of processors
Definition: world.h:26
MPI_Comm comm
set of processors making up this world
Definition: world.h:22
const char * get_fmt< int64_t >()
void parse_sparse_tensor_data(char **lvals, int order, dtype const *pmulid, int *lens, int64_t nvals, CTF::Pair< dtype > *pairs, bool with_vals)
parse string containing sparse tensor into data