Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / src / smpi / bindings / smpi_pmpi_file.cpp
1 /* Copyright (c) 2007-2023. 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   CHECK_NULL(1, MPI_ERR_FILE, filename)
268   const SmpiBenchGuard suspend_bench;
269   int ret = simgrid::smpi::File::del(filename, info);
270   return ret;
271 }
272
273 int PMPI_File_set_view(MPI_File fh, MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, const char *datarep, MPI_Info info){
274   CHECK_FILE(1, fh)
275   CHECK_COLLECTIVE(fh->comm(), __func__)
276   if(not ((fh->flags() & MPI_MODE_SEQUENTIAL) && (disp == MPI_DISPLACEMENT_CURRENT)))
277     CHECK_OFFSET(2, disp)
278   CHECK_TYPE(3, etype)
279   CHECK_TYPE(4, filetype)
280   const SmpiBenchGuard suspend_bench;
281   int ret = fh->set_view(disp, etype, filetype, datarep, info);
282   return ret;
283 }
284
285 int PMPI_File_get_view(MPI_File fh, MPI_Offset *disp, MPI_Datatype *etype, MPI_Datatype *filetype, char *datarep){
286   CHECK_FILE(1, fh)
287   CHECK_NULL(2, MPI_ERR_ARG, disp)
288   CHECK_NULL(3, MPI_ERR_ARG, etype)
289   CHECK_NULL(4, MPI_ERR_ARG, filetype)
290   const SmpiBenchGuard suspend_bench;
291   int ret = fh->get_view(disp, etype, filetype, datarep);
292   return ret;
293 }
294
295 int PMPI_File_get_info(MPI_File  fh, MPI_Info* info)
296 {
297   CHECK_FILE(1, fh)
298   *info = new simgrid::smpi::Info(fh->info());
299   return MPI_SUCCESS;
300 }
301
302 int PMPI_File_set_info(MPI_File  fh, MPI_Info info)
303 {
304   CHECK_FILE(1, fh)
305   fh->set_info(info);
306   return MPI_SUCCESS;
307 }
308
309 int PMPI_File_get_size(MPI_File  fh, MPI_Offset* size)
310 {
311   CHECK_FILE(1, fh)
312   *size = fh->size();
313   return MPI_SUCCESS;
314 }
315
316 int PMPI_File_set_size(MPI_File  fh, MPI_Offset size)
317 {
318   CHECK_FILE(1, fh)
319   CHECK_COLLECTIVE(fh->comm(), __func__)
320   fh->set_size(size);
321   return MPI_SUCCESS;
322 }
323
324 int PMPI_File_get_amode(MPI_File  fh, int* amode)
325 {
326   CHECK_FILE(1, fh)
327   *amode = fh->flags();
328   return MPI_SUCCESS;
329 }
330
331 int PMPI_File_get_group(MPI_File  fh, MPI_Group* group)
332 {
333   CHECK_FILE(1, fh)
334   *group = fh->comm()->group();
335   return MPI_SUCCESS;
336 }
337
338 int PMPI_File_sync(MPI_File  fh)
339 {
340   CHECK_FILE(1, fh)
341   fh->sync();
342   return MPI_SUCCESS;
343 }
344
345 int PMPI_File_create_errhandler(MPI_File_errhandler_function* function, MPI_Errhandler* errhandler){
346   *errhandler=new simgrid::smpi::Errhandler(function);
347   return MPI_SUCCESS;
348 }
349
350 int PMPI_File_get_errhandler(MPI_File file, MPI_Errhandler* errhandler){
351   if (errhandler==nullptr){
352     return MPI_ERR_ARG;
353   } else if (file == MPI_FILE_NULL) {
354     *errhandler = SMPI_default_File_Errhandler;
355     return MPI_SUCCESS;
356   }
357   *errhandler=file->errhandler();
358   return MPI_SUCCESS;
359 }
360
361 int PMPI_File_set_errhandler(MPI_File file, MPI_Errhandler errhandler){
362   if (errhandler==nullptr){
363     return MPI_ERR_ARG;
364   } else if (file == MPI_FILE_NULL) {
365     SMPI_default_File_Errhandler = errhandler;
366     return MPI_SUCCESS;
367   }
368   file->set_errhandler(errhandler);
369   return MPI_SUCCESS;
370 }
371
372 int PMPI_File_call_errhandler(MPI_File file,int errorcode){
373   CHECK_FILE(1, file)
374   MPI_Errhandler err = file->errhandler();
375   err->call(file, errorcode);
376   simgrid::smpi::Errhandler::unref(err);
377   return MPI_SUCCESS;
378 }
379
380 int PMPI_File_get_type_extent(MPI_File fh, MPI_Datatype
381     datatype, MPI_Aint *extent){
382   CHECK_FILE(1, fh)
383   CHECK_TYPE(2, datatype)
384   CHECK_NULL(3, MPI_ERR_OTHER, extent)
385   *extent = datatype->get_extent();
386   return MPI_SUCCESS;
387 }
388
389 int PMPI_File_set_atomicity(MPI_File fh, int a){
390   CHECK_FILE(1, fh)
391   fh->set_atomicity(a != 0);
392   return MPI_SUCCESS;
393 }
394
395 int PMPI_File_get_atomicity(MPI_File fh, int* a){
396   CHECK_FILE(1, fh)
397   *a = fh->get_atomicity();
398   return MPI_SUCCESS;
399 }
400
401 int PMPI_File_get_byte_offset(MPI_File fh, MPI_Offset offset, MPI_Offset *disp){
402   CHECK_FILE(1, fh)
403   CHECK_NULL(3, MPI_ERR_OTHER, disp)
404   *disp = offset * fh->etype()->get_extent();
405   return MPI_SUCCESS;
406 }