Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
seek and other calls must use number of elements and not bytes displacement
[simgrid.git] / src / smpi / bindings / smpi_pmpi_file.cpp
1 /* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "private.hpp"
7
8 #include "smpi_file.hpp"
9 #include "smpi_datatype.hpp"
10
11 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
12 #define CHECK_RDONLY(fh)                                                                                               \
13   if ((fh)->flags() & MPI_MODE_RDONLY)                                                                                 \
14     return MPI_ERR_AMODE;
15 #define CHECK_WRONLY(fh)                                                                                               \
16   if ((fh)->flags() & MPI_MODE_WRONLY)                                                                                 \
17     return MPI_ERR_AMODE;
18 #define PASS_ZEROCOUNT(count)                                                                                          \
19   if ((count) == 0) {                                                                                                  \
20     status->count = 0;                                                                                                 \
21     return MPI_SUCCESS;                                                                                                \
22   }
23
24 #define CHECK_FILE_INPUTS                                                                                              \
25   CHECK_FILE(1, fh)                                                                                                    \
26   CHECK_COUNT(3, count)                                                                                                \
27   CHECK_TYPE(4, datatype)                                                                                              \
28   CHECK_BUFFER(2, buf, count, datatype)                                                                                          \
29
30 #define CHECK_FILE_INPUT_OFFSET                                                                                        \
31   CHECK_FILE(1, fh)                                                                                                    \
32   CHECK_OFFSET(3, offset)                                                                                                 \
33   CHECK_COUNT(4, count)                                                                                                \
34   CHECK_TYPE(5, datatype)                                                                                              \
35   CHECK_BUFFER(2, buf, count, datatype)                                                                                          \
36
37 extern MPI_Errhandler SMPI_default_File_Errhandler;
38
39 int PMPI_File_open(MPI_Comm comm, const char *filename, int amode, MPI_Info info, MPI_File *fh){
40   CHECK_COMM(1)
41   CHECK_COLLECTIVE(comm, "MPI_File_open")
42   CHECK_NULL(2, MPI_ERR_FILE, filename)
43   if (amode < 0)
44     return MPI_ERR_AMODE;
45   const SmpiBenchGuard suspend_bench;
46   *fh =  new simgrid::smpi::File(comm, filename, amode, info);
47   if ((*fh)->size() != 0 && (amode & MPI_MODE_EXCL)){
48     delete fh;
49     return MPI_ERR_AMODE;
50   }
51   if(amode & MPI_MODE_APPEND)
52     (*fh)->seek(0,MPI_SEEK_END);
53   return MPI_SUCCESS;
54 }
55
56 int PMPI_File_close(MPI_File *fh){
57   CHECK_NULL(2, MPI_ERR_ARG, fh)
58   CHECK_COLLECTIVE((*fh)->comm(), __func__)
59   const SmpiBenchGuard suspend_bench;
60   int ret = simgrid::smpi::File::close(fh);
61   *fh = MPI_FILE_NULL;
62   return ret;
63 }
64
65 int PMPI_File_seek(MPI_File fh, MPI_Offset offset, int whence){
66   CHECK_FILE(1, fh)
67   const SmpiBenchGuard suspend_bench;
68   int ret = fh->seek(offset*fh->etype()->get_extent(),whence);
69   return ret;
70 }
71
72 int PMPI_File_seek_shared(MPI_File fh, MPI_Offset offset, int whence){
73   CHECK_FILE(1, fh)
74   CHECK_COLLECTIVE(fh->comm(), __func__)
75   const SmpiBenchGuard suspend_bench;
76   int ret = fh->seek_shared(offset*fh->etype()->get_extent(),whence);
77   return ret;
78 }
79
80 int PMPI_File_get_position(MPI_File fh, MPI_Offset* offset){
81   CHECK_FILE(1, fh)
82   CHECK_NULL(2, MPI_ERR_DISP, offset)
83   const SmpiBenchGuard suspend_bench;
84   int ret = fh->get_position(offset);
85   return ret;
86 }
87
88 int PMPI_File_get_position_shared(MPI_File fh, MPI_Offset* offset){
89   CHECK_FILE(1, fh)
90   CHECK_NULL(2, MPI_ERR_DISP, offset)
91   const SmpiBenchGuard suspend_bench;
92   int ret = fh->get_position_shared(offset);
93   return ret;
94 }
95
96 int PMPI_File_read(MPI_File fh, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
97   CHECK_FILE_INPUTS
98   CHECK_WRONLY(fh)
99   PASS_ZEROCOUNT(count)
100   const SmpiBenchGuard suspend_bench;
101   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
102   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - read", count * datatype->size()));
103   int ret = simgrid::smpi::File::read(fh, buf, count, datatype, status);
104   TRACE_smpi_comm_out(rank_traced);
105   return ret;
106 }
107
108 int PMPI_File_read_shared(MPI_File fh, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
109   CHECK_FILE_INPUTS
110   CHECK_WRONLY(fh)
111   PASS_ZEROCOUNT(count)
112   const SmpiBenchGuard suspend_bench;
113   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
114   TRACE_smpi_comm_in(rank_traced, __func__,
115                      new simgrid::instr::CpuTIData("IO - read_shared", count * datatype->size()));
116   int ret = simgrid::smpi::File::read_shared(fh, buf, count, datatype, status);
117   TRACE_smpi_comm_out(rank_traced);
118   return ret;
119 }
120
121 int PMPI_File_write(MPI_File fh, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
122   CHECK_FILE_INPUTS
123   CHECK_RDONLY(fh)
124   PASS_ZEROCOUNT(count)
125   const SmpiBenchGuard suspend_bench;
126   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
127   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - write", count * datatype->size()));
128   int ret = simgrid::smpi::File::write(fh, const_cast<void*>(buf), count, datatype, status);
129   TRACE_smpi_comm_out(rank_traced);
130   return ret;
131 }
132
133 int PMPI_File_write_shared(MPI_File fh, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
134   CHECK_FILE_INPUTS
135   CHECK_RDONLY(fh)
136   PASS_ZEROCOUNT(count)
137   const SmpiBenchGuard suspend_bench;
138   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
139   TRACE_smpi_comm_in(rank_traced, __func__,
140                      new simgrid::instr::CpuTIData("IO - write_shared", count * datatype->size()));
141   int ret = simgrid::smpi::File::write_shared(fh, buf, count, datatype, status);
142   TRACE_smpi_comm_out(rank_traced);
143   return ret;
144 }
145
146 int PMPI_File_read_all(MPI_File fh, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
147   CHECK_FILE_INPUTS
148   CHECK_WRONLY(fh)
149   CHECK_COLLECTIVE(fh->comm(), __func__)
150   const SmpiBenchGuard suspend_bench;
151   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
152   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - read_all", count * datatype->size()));
153   int ret = fh->op_all<simgrid::smpi::File::read>(buf, count, datatype, status);
154   TRACE_smpi_comm_out(rank_traced);
155   return ret;
156 }
157
158 int PMPI_File_read_ordered(MPI_File fh, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
159   CHECK_FILE_INPUTS
160   CHECK_WRONLY(fh)
161   CHECK_COLLECTIVE(fh->comm(), __func__)
162   const SmpiBenchGuard suspend_bench;
163   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
164   TRACE_smpi_comm_in(rank_traced, __func__,
165                      new simgrid::instr::CpuTIData("IO - read_ordered", count * datatype->size()));
166   int ret = simgrid::smpi::File::read_ordered(fh, buf, count, datatype, status);
167   TRACE_smpi_comm_out(rank_traced);
168   return ret;
169 }
170
171 int PMPI_File_write_all(MPI_File fh, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
172   CHECK_FILE_INPUTS
173   CHECK_RDONLY(fh)
174   CHECK_COLLECTIVE(fh->comm(), __func__)
175   const SmpiBenchGuard suspend_bench;
176   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
177   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - write_all", count * datatype->size()));
178   int ret = fh->op_all<simgrid::smpi::File::write>(const_cast<void*>(buf), count, datatype, status);
179   TRACE_smpi_comm_out(rank_traced);
180   return ret;
181 }
182
183 int PMPI_File_write_ordered(MPI_File fh, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
184   CHECK_FILE_INPUTS
185   CHECK_RDONLY(fh)
186   CHECK_COLLECTIVE(fh->comm(), __func__)
187   const SmpiBenchGuard suspend_bench;
188   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
189   TRACE_smpi_comm_in(rank_traced, __func__,
190                      new simgrid::instr::CpuTIData("IO - write_ordered", count * datatype->size()));
191   int ret = simgrid::smpi::File::write_ordered(fh, buf, count, datatype, status);
192   TRACE_smpi_comm_out(rank_traced);
193   return ret;
194 }
195
196 int PMPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
197   CHECK_FILE_INPUTS
198   CHECK_WRONLY(fh)
199   PASS_ZEROCOUNT(count)
200   const SmpiBenchGuard suspend_bench;
201   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
202   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - read", count * datatype->size()));
203   MPI_Offset prev;
204   fh->get_position(&prev);
205   int ret = fh->seek(offset,MPI_SEEK_SET);
206   if (ret == MPI_SUCCESS)
207     ret = simgrid::smpi::File::read(fh, buf, count, datatype, status);
208   fh->seek(prev,MPI_SEEK_SET);
209   TRACE_smpi_comm_out(rank_traced);
210   return ret;
211 }
212
213 int PMPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
214   CHECK_FILE_INPUT_OFFSET
215   CHECK_WRONLY(fh)
216   CHECK_COLLECTIVE(fh->comm(), __func__)
217   const SmpiBenchGuard suspend_bench;
218   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
219   TRACE_smpi_comm_in(rank_traced, __func__,
220                      new simgrid::instr::CpuTIData("IO - read_at_all", count * datatype->size()));
221   MPI_Offset prev;
222   fh->get_position(&prev);
223   int ret = fh->seek(offset,MPI_SEEK_SET);
224   if (ret == MPI_SUCCESS)
225     ret = fh->op_all<simgrid::smpi::File::read>(buf, count, datatype, status);
226   fh->seek(prev,MPI_SEEK_SET);
227   TRACE_smpi_comm_out(rank_traced);
228   return ret;
229 }
230
231 int PMPI_File_write_at(MPI_File fh, MPI_Offset offset, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
232   CHECK_FILE_INPUT_OFFSET
233   CHECK_RDONLY(fh)
234   PASS_ZEROCOUNT(count)
235   const SmpiBenchGuard suspend_bench;
236   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
237   TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::CpuTIData("IO - write", count * datatype->size()));
238   MPI_Offset prev;
239   fh->get_position(&prev);
240   int ret = fh->seek(offset,MPI_SEEK_SET);
241   if (ret == MPI_SUCCESS)
242     ret = simgrid::smpi::File::write(fh, const_cast<void*>(buf), count, datatype, status);
243   fh->seek(prev,MPI_SEEK_SET);
244   TRACE_smpi_comm_out(rank_traced);
245   return ret;
246 }
247
248 int PMPI_File_write_at_all(MPI_File fh, MPI_Offset offset, const void *buf, int count,MPI_Datatype datatype, MPI_Status *status){
249   CHECK_FILE_INPUT_OFFSET
250   CHECK_RDONLY(fh)
251   CHECK_COLLECTIVE(fh->comm(), __func__)
252   const SmpiBenchGuard suspend_bench;
253   aid_t rank_traced = simgrid::s4u::this_actor::get_pid();
254   TRACE_smpi_comm_in(rank_traced, __func__,
255                      new simgrid::instr::CpuTIData("IO - write_at_all", count * datatype->size()));
256   MPI_Offset prev;
257   fh->get_position(&prev);
258   int ret = fh->seek(offset,MPI_SEEK_SET);
259   if (ret == MPI_SUCCESS)
260     ret = fh->op_all<simgrid::smpi::File::write>(const_cast<void*>(buf), count, datatype, status);
261   fh->seek(prev,MPI_SEEK_SET);
262   TRACE_smpi_comm_out(rank_traced);
263   return ret;
264 }
265
266 int PMPI_File_delete(const char *filename, MPI_Info info){
267   if (filename == nullptr)
268     return MPI_ERR_FILE;
269   const SmpiBenchGuard suspend_bench;
270   int ret = simgrid::smpi::File::del(filename, info);
271   return ret;
272 }
273
274 int PMPI_File_set_view(MPI_File fh, MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, const char *datarep, MPI_Info info){
275   CHECK_FILE(1, fh)
276   CHECK_COLLECTIVE(fh->comm(), __func__)
277   if(not ((fh->flags() & MPI_MODE_SEQUENTIAL) && (disp == MPI_DISPLACEMENT_CURRENT)))
278     CHECK_OFFSET(2, disp)
279   CHECK_TYPE(3, etype)
280   CHECK_TYPE(4, filetype)
281   const SmpiBenchGuard suspend_bench;
282   int ret = fh->set_view(disp, etype, filetype, datarep, info);
283   return ret;
284 }
285
286 int PMPI_File_get_view(MPI_File fh, MPI_Offset *disp, MPI_Datatype *etype, MPI_Datatype *filetype, char *datarep){
287   CHECK_FILE(1, fh)
288   CHECK_NULL(2, MPI_ERR_ARG, disp)
289   CHECK_NULL(3, MPI_ERR_ARG, etype)
290   CHECK_NULL(4, MPI_ERR_ARG, filetype)
291   const SmpiBenchGuard suspend_bench;
292   int ret = fh->get_view(disp, etype, filetype, datarep);
293   return ret;
294 }
295
296 int PMPI_File_get_info(MPI_File  fh, MPI_Info* info)
297 {
298   CHECK_FILE(1, fh)
299   *info = new simgrid::smpi::Info(fh->info());
300   return MPI_SUCCESS;
301 }
302
303 int PMPI_File_set_info(MPI_File  fh, MPI_Info info)
304 {
305   CHECK_FILE(1, fh)
306   fh->set_info(info);
307   return MPI_SUCCESS;
308 }
309
310 int PMPI_File_get_size(MPI_File  fh, MPI_Offset* size)
311 {
312   CHECK_FILE(1, fh)
313   *size = fh->size();
314   return MPI_SUCCESS;
315 }
316
317 int PMPI_File_set_size(MPI_File  fh, MPI_Offset size)
318 {
319   CHECK_FILE(1, fh)
320   CHECK_COLLECTIVE(fh->comm(), __func__)
321   fh->set_size(size);
322   return MPI_SUCCESS;
323 }
324
325 int PMPI_File_get_amode(MPI_File  fh, int* amode)
326 {
327   CHECK_FILE(1, fh)
328   *amode = fh->flags();
329   return MPI_SUCCESS;
330 }
331
332 int PMPI_File_get_group(MPI_File  fh, MPI_Group* group)
333 {
334   CHECK_FILE(1, fh)
335   *group = fh->comm()->group();
336   return MPI_SUCCESS;
337 }
338
339 int PMPI_File_sync(MPI_File  fh)
340 {
341   CHECK_FILE(1, fh)
342   fh->sync();
343   return MPI_SUCCESS;
344 }
345
346 int PMPI_File_create_errhandler(MPI_File_errhandler_function* function, MPI_Errhandler* errhandler){
347   *errhandler=new simgrid::smpi::Errhandler(function);
348   return MPI_SUCCESS;
349 }
350
351 int PMPI_File_get_errhandler(MPI_File file, MPI_Errhandler* errhandler){
352   if (errhandler==nullptr){
353     return MPI_ERR_ARG;
354   } else if (file == MPI_FILE_NULL) {
355     *errhandler = SMPI_default_File_Errhandler;
356     return MPI_SUCCESS;
357   }
358   *errhandler=file->errhandler();
359   return MPI_SUCCESS;
360 }
361
362 int PMPI_File_set_errhandler(MPI_File file, MPI_Errhandler errhandler){
363   if (errhandler==nullptr){
364     return MPI_ERR_ARG;
365   } else if (file == MPI_FILE_NULL) {
366     SMPI_default_File_Errhandler = errhandler;
367     return MPI_SUCCESS;
368   }
369   file->set_errhandler(errhandler);
370   return MPI_SUCCESS;
371 }
372
373 int PMPI_File_call_errhandler(MPI_File file,int errorcode){
374   if (file == nullptr) {
375     return MPI_ERR_WIN;
376   }
377   MPI_Errhandler err = file->errhandler();
378   err->call(file, errorcode);
379   simgrid::smpi::Errhandler::unref(err);
380   return MPI_SUCCESS;
381 }
382
383 int PMPI_File_get_type_extent(MPI_File fh, MPI_Datatype
384     datatype, MPI_Aint *extent){
385   CHECK_FILE(1, fh)
386   CHECK_TYPE(2, datatype)
387   CHECK_NULL(3, MPI_ERR_OTHER, extent)
388   *extent = datatype->get_extent();
389   return MPI_SUCCESS;
390 }
391
392 int PMPI_File_set_atomicity(MPI_File fh, int a){
393   CHECK_FILE(1, fh)
394   fh->set_atomicity(a != 0);
395   return MPI_SUCCESS;
396 }
397
398 int PMPI_File_get_atomicity(MPI_File fh, int* a){
399   CHECK_FILE(1, fh)
400   *a = fh->get_atomicity();
401   return MPI_SUCCESS;
402 }
403
404 int PMPI_File_get_byte_offset(MPI_File fh, MPI_Offset offset, MPI_Offset *disp){
405   CHECK_FILE(1, fh)
406   CHECK_NULL(3, MPI_ERR_OTHER, disp)
407   *disp = offset * fh->etype()->get_extent();
408   return MPI_SUCCESS;
409 }