SIONlib  1.7.7
Scalable I/O library for parallel access to task-local files
sion_buffer.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2019 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 #define _XOPEN_SOURCE 700
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <time.h>
15 #include <assert.h>
16 
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 
22 #ifdef _SION_CUDA
23 #include <cuda_runtime.h>
24 #endif
25 
26 #include "sion.h"
27 #include "sion_debug.h"
28 #include "sion_error_handler.h"
29 #include "sion_internal.h"
30 #include "sion_buffer.h"
31 
32 
33 #if defined(_SION_LINUX)
34 #elif defined(_SION_AIX)
35 #elif defined(_SION_BGP)
36 #endif
37 
38 
53 #define DFUNCTION "_sion_buffer_check_env"
61  const char *t;
62  int rc = SION_SUCCESS;
63  t = _sion_getenv("SION_BUFFERSIZE");
64  if(t) {
65  sion_filedesc->buffer_size=atoi(t);
66  if(sion_filedesc->buffer_size == -1) sion_filedesc->buffer_size=sion_filedesc->fsblksize;
67  }
68  DPRINTFP((2, DFUNCTION, -1, "buffersize=%d\n", sion_filedesc->buffer_size));
69  _sion_buffer_init(sion_filedesc);
70  return (rc);
71 }
72 #undef DFUNCTION
73 
74 #define DFUNCTION "_sion_buffer_init"
81 int _sion_buffer_init(_sion_filedesc *sion_filedesc) {
82  int rc = SION_SUCCESS;
83 
84  /* allocation */
85  if(sion_filedesc->buffer_size>0) {
86  sion_filedesc->buffer = (char *) malloc(sion_filedesc->buffer_size);
87  if (sion_filedesc->buffer == NULL) {
88  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_buffer_init: cannot allocate internal buffer of size %lu , aborting ...\n", (unsigned long) sion_filedesc->buffer_size));
89  }
90  sion_filedesc->usebuffer=1;
91  DPRINTFP((2, DFUNCTION, -1, "buffer with size=%d allocated\n", sion_filedesc->buffer_size));
92  }
93  return (rc);
94 }
95 #undef DFUNCTION
96 
97 #define DFUNCTION "_sion_buffer_push"
106 sion_int64 _sion_buffer_push(_sion_filedesc *sion_filedesc,
107  const void *data, sion_int64 bytes) {
108  sion_int64 bytes_free;
109  sion_int64 bytes_stored;
110  ONLY_DEBUG(sion_int64 bytes_not_stored;)
111  /* allocation */
112  bytes_free=sion_filedesc->buffer_size-sion_filedesc->buffer_ptr;
113  if(bytes<bytes_free) { /* data fits in buffer */
114  bytes_stored=bytes;
115  ONLY_DEBUG(bytes_not_stored=0;)
116  } else {
117  bytes_stored=bytes_free;
118  ONLY_DEBUG(bytes_not_stored=bytes-bytes_stored;)
119  }
120  if(bytes_stored>0) {
121 #ifdef _SION_CUDA
122  struct cudaPointerAttributes attrs;
123  cudaError_t err = cudaPointerGetAttributes(&attrs, data);
124  if ((err == cudaSuccess) && _sion_cuda_ptr_is_device(attrs) ) {
125  cudaMemcpy(sion_filedesc->buffer + sion_filedesc->buffer_ptr, data, bytes_stored, cudaMemcpyDeviceToHost);
126  } else {
127  memcpy(sion_filedesc->buffer+sion_filedesc->buffer_ptr,data,bytes_stored);
128  }
129 #else
130  memcpy(sion_filedesc->buffer+sion_filedesc->buffer_ptr,data,bytes_stored);
131 #endif
132  sion_filedesc->buffer_ptr+=bytes_stored;
133  }
134 
135  DPRINTFP((2, DFUNCTION, -1, "pushed %d of %d bytes into buffer -> ptr=%d ret=%d\n",
136  (int) bytes_stored,(int) bytes,
137  (int) sion_filedesc->buffer_ptr, (int) bytes_not_stored));
138  return (bytes_stored);
139 }
140 #undef DFUNCTION
141 
142 #define DFUNCTION "_sion_buffer_get_data_ptr"
153  void **data, sion_int64 *bytes) {
154  int flag = 0;
155 
156  /* pointer to and size of actual buffer contents */
157  *data=sion_filedesc->buffer;
158  *bytes=sion_filedesc->buffer_ptr;
159  flag=(*bytes>0);
160 
161  /* empty buffer */
162  sion_filedesc->buffer_ptr=0;
163  DPRINTFP((2, DFUNCTION, -1, "returns data ptr to %d bytes, flag=%d\n",
164  (int) *bytes, flag));
165 
166  return (flag);
167 }
168 #undef DFUNCTION
169 
170 #define DFUNCTION "_sion_buffer_flush"
177 int _sion_buffer_flush(_sion_filedesc *sion_filedesc) {
178  sion_int64 bbytes, frc, byteswritten;
179  void *bdata;
180 
181 
182  DPRINTFP((1, DFUNCTION, -1, "enter\n"));
183 
184  _sion_flush_block(sion_filedesc);
185 
186  byteswritten = sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
187 
188  _sion_buffer_get_data_ptr(sion_filedesc,&bdata,&bbytes);
189 
190  if ((byteswritten + bbytes) > sion_filedesc->chunksize) {
191  /* not enough space for writing next data */
192  _sion_create_new_block(sion_filedesc);
193  }
194 
195  frc = _sion_file_write(bdata, bbytes, sion_filedesc->fileptr);
196  if(frc != bbytes) {
197  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
198  "could not write data (%d bytes) to file (sid=%d) ...", (int) bbytes, sion_filedesc->sid));
199  }
200  sion_filedesc->currentpos+=bbytes;
201 
202  DPRINTFP((2, DFUNCTION, -1, "leave\n"));
203 
204  return (SION_SUCCESS);
205 }
206 #undef DFUNCTION
int _sion_buffer_check_env(_sion_filedesc *sion_filedesc)
Checks if environment variables are set to use buffer.
Definition: sion_buffer.c:60
int _sion_buffer_get_data_ptr(_sion_filedesc *sion_filedesc, void **data, sion_int64 *bytes)
Pop all data from buffer.
Definition: sion_buffer.c:152
int _sion_buffer_init(_sion_filedesc *sion_filedesc)
Allocate and initalize the buffer.
Definition: sion_buffer.c:81
int _sion_buffer_flush(_sion_filedesc *sion_filedesc)
Flush buffer.
Definition: sion_buffer.c:177
sion_int64 _sion_buffer_push(_sion_filedesc *sion_filedesc, const void *data, sion_int64 bytes)
Push data to buffer.
Definition: sion_buffer.c:106
sion_int64 _sion_file_write(const void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr)
Write data to file.
Definition: sion_file.c:221
int _sion_create_new_block(_sion_filedesc *sion_filedesc)
Create a new block for the internal data structure.
char * _sion_getenv(const char *name)
int _sion_flush_block(_sion_filedesc *sion_filedesc)
Update the internal data structure.
Sion File Descriptor Structure.
Definition: sion_filedesc.h:79
sion_int64 * blocksizes
sion_int32 currentblocknr
Definition: sion_filedesc.h:97
_sion_fileptr * fileptr
Definition: sion_filedesc.h:82