SIONlib  1.7.7
Scalable I/O library for parallel access to task-local files
sion_omp_gen.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 ****************************************************************************/
17 #define _XOPEN_SOURCE 700
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include <sys/time.h>
26 
27 #include <sys/types.h>
28 #include <fcntl.h>
29 
30 #include <unistd.h>
31 
32 #include "omp.h"
33 
34 #include "sion.h"
35 #include "sion_debug.h"
36 #include "sion_error_handler.h"
37 #include "sion_internal.h"
38 #include "sion_fd.h"
39 #include "sion_filedesc.h"
40 #include "sion_printts.h"
41 #include "sion_flags.h"
42 
43 #include "sion_generic.h"
44 
45 #include "sion_omp.h"
46 #include "sion_omp_internal_gen.h"
47 #include "sion_omp_cb_gen.h"
48 #include "sion_lock.h"
49 
50 
51 #ifdef SION_OMP
52 
53 
54 sion_int32 _sion_omp_api_aid = -1;
55 static omp_lock_t _sion_omp_lock_data;
56 
57 int _sion_omp_user_lock(void * data) {
58  int rc=SION_SUCCESS;
59  omp_set_lock(&_sion_omp_lock_data);
60  return(rc);
61 }
62 int _sion_omp_user_unlock(void * data) {
63  int rc=SION_SUCCESS;
64  omp_unset_lock(&_sion_omp_lock_data);
65  return(rc);
66 }
67 
85 int sion_paropen_omp(const char *fname,
86  const char *file_mode,
87  sion_int64 *chunksize,
88  sion_int32 *fsblksize,
89  int *globalrank,
90  FILE **fileptr,
91  char **newfname)
92 {
93  int sid = SION_ID_UNDEF;
94  int filenumber, num_threads, thread_num;
95  int numFiles=1,gtasks, gRank, lRank, lSize;
96  _omp_api_commdata *gen_gcomm;
97  _sion_flags_store* flags_store = NULL;
98 
99  thread_num = omp_get_thread_num();
100  num_threads = omp_get_num_threads();
101 
102  #pragma omp master
103  {
104  _sion_debug_set_query_thread_num_function(omp_get_thread_num);
105  _sion_error_set_query_thread_num_function(omp_get_thread_num);
106  omp_init_lock(&_sion_omp_lock_data);
107  sion_lock_register_lock_callbacks(_sion_omp_user_lock,_sion_omp_user_unlock,&_sion_omp_lock_data);
108  }
109  {
110  #pragma omp barrier
111  }
112 
113  DPRINTFP((1, "sion_paropen_omp", thread_num, "enter parallel open of file %s\n", fname));
114 
115  flags_store = _sion_parse_flags(file_mode);
116  if ( ! flags_store ) {
117  return(_sion_errorprint_omp(SION_ID_NOT_VALID,_SION_ERROR_RETURN,
118  "sion_paropen_omp: could not parse file mode in %s, aborting ...\n", file_mode));
119  }
120 
121  if (flags_store->mask&_SION_FMODE_WRITE) {
122  /* file mode WRITE */
123  *globalrank = thread_num;
124  }
125  if (_sion_flags_get(flags_store, "collmsa")) {
126  _sion_flags_destroy_store(&flags_store);
127  return _sion_errorprint(SION_ID_NOT_VALID, _SION_ERROR_ABORT, "sion_paropen_omp: MSA aware collective operations not supported with OpenMP API, aborting ...\n");
128  }
129  _sion_flags_destroy_store(&flags_store);
130 
131  #pragma omp master
132  {
133  /* register callbacks for generic interface */
134  if(_sion_omp_api_aid<0) _sion_omp_api_aid=_sion_register_callbacks_omp();
135  }
136 
137  /* create generic communicator container */
138  gen_gcomm = (_omp_api_commdata *) malloc(sizeof(_omp_api_commdata));
139  if (gen_gcomm == NULL) {
140  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,
141  "cannot allocate omp internal data structure of size %lu (_omp_api_commdata), aborting ...\n",
142  (unsigned long) sizeof(_omp_api_commdata)));
143  }
144  gen_gcomm->commset=1;
145  gen_gcomm->thread_num=thread_num;
146  gen_gcomm->num_threads=num_threads;
147 
148  /* sync to ensure that aid is accessible */
149  _sion_omp_barrier_cb(gen_gcomm);
150 
151 
152  lRank=gRank=thread_num;
153  lSize=gtasks=num_threads;
154  filenumber=0;
155  numFiles=1;
156 
157  DPRINTFP((1, "sion_paropen_omp", gRank, "enter parallel open of %d files (current name %s) in %s mode\n", numFiles, fname, file_mode));
158  sid = sion_generic_paropen(_sion_omp_api_aid, fname, file_mode, chunksize, fsblksize, gen_gcomm, gRank, gtasks,
159  &filenumber, &numFiles, &lRank, &lSize, fileptr, newfname);
160  DPRINTFP((1, "sion_paropen_omp", gRank, "leave parallel open of %d files in %s mode #tasks=%d sid=%d\n", numFiles, file_mode, lSize, sid));
161 
162 
163  /* test return code from internal open */
164  if ( sid == SION_ID_NOT_VALID ) {
165  return(_sion_errorprint_omp(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"sion_paropen_omp: invalid return code from internal open %d", sid));
166  }
167 
168  DPRINTFP((1, "sion_paropen_omp", thread_num, "leave parallel open of file %s sid=%d\n", fname, sid));
169 
170  return (sid);
171 }
172 
179 int sion_parclose_omp(int sid)
180 {
181  int rc = SION_SUCCESS;
182  ONLY_DEBUG(int thread_num;)
183  _sion_filedesc *sion_filedesc;
184 
185  if ( (sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
186  return(_sion_errorprint_omp(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_parclose_omp: invalid sion_filedesc %d", sid));
187  }
188 
189  ONLY_DEBUG(thread_num = omp_get_thread_num();)
190 
191  if(omp_get_num_threads()!=sion_filedesc->ntasks){
192  return(_sion_errorprint_omp(SION_NOT_SUCCESS,_SION_ERROR_RETURN,
193  "sion_parclose_omp: invalid number of OpenMP threads, %d <> %d",
194  omp_get_num_threads(), sion_filedesc->ntasks));
195  }
196 
197  DPRINTFP((1, "sion_parclose_omp", thread_num, "enter parallel close of sid %d\n", sid));
198  DPRINTFP((1, "sion_parclose_omp", thread_num, "closing %d file(s)\n", sion_filedesc->nfiles));
199 
200  rc = sion_generic_parclose(sid);
201 
202  DPRINTFP((1, "sion_parclose_omp", thread_num, "leave parallel close of sid %d rc=%d\n", sid, rc));
203  return rc;
204 }
205 
206 /* end of ifdef OMP */
207 #endif
callback wrappers for OMP thread safe fd manipulation
int sion_lock_register_lock_callbacks(int lock(void *), int unlock(void *), void *lock_data)
Function which registers callback funtions for lock and unlock internal access to shared data structu...
Definition: sion_common.c:1220
void * _sion_vcdtovcon(int sid)
Definition: sion_fd.c:53
int _sion_vcdtype(int sid)
Definition: sion_fd.c:58
#define SION_FILEDESCRIPTOR
Definition: sion_fd.h:17
_sion_flags_store * _sion_parse_flags(const char *flags)
Parse flags and return a flags store with key value pairs.
Definition: sion_flags.c:326
int sion_generic_paropen(int aid, const char *fname, const char *file_mode, sion_int64 *chunksize, sion_int32 *fsblksize, void *gcommgroup, int grank, int gsize, int *filenumber, int *numfiles, const int *lrank, const int *lsize, FILE **fileptr, char **newfname)
Open a sion file a generic interface.
Definition: sion_generic.c:351
Sion Time Stamp Header.
Sion File Descriptor Structure.
Definition: sion_filedesc.h:79