source: XIOS/trunk/src/interface/c/icdata.cpp @ 489

Last change on this file since 489 was 489, checked in by mhnguyen, 10 years ago

Ticket 50: Implementing the getting/setting methods for Fortran interface

+) Add some C and Fortran functions to set and get data to/from CVariable with an id
+) Add method to send, receive and dispatch in CVariable
+) Add dispatch method in server class

Test
-) On Curie
-) Test data: integer, float, double, boolean, string
-) File: one and multiple, using_server: ON and OFF
+) All test cases passed and had correct results

  • Property svn:eol-style set to native
File size: 15.7 KB
RevLine 
[325]1/* ************************************************************************** *
[335]2 *      Copyright © IPSL/LSCE, xios, Avril 2010 - Octobre 2011         *
[325]3 * ************************************************************************** */
4
5#include <boost/multi_array.hpp>
6#include <boost/shared_ptr.hpp>
7#include <string>
[489]8#include <cstring>
[325]9#include <iostream>
10
11
12#include "xmlioserver.hpp"
13#include "oasis_cinterface.hpp"
14
[352]15#include "attribute_template.hpp"
16#include "object_template.hpp"
17#include "group_template.hpp"
[325]18
19#include "icutil.hpp"
20#include "cxios.hpp"
[342]21#include "client.hpp"
[325]22#include "field.hpp"
[352]23#include "context.hpp"
[403]24#include "context_client.hpp"
[382]25#include "mpi.hpp"
[347]26#include "timer.hpp"
[369]27#include "array_new.hpp"
[325]28
[403]29
[325]30extern "C"
31{
32// /////////////////////////////// Définitions ////////////////////////////// //
33
34   // ----------------------- Redéfinition de types ----------------------------
[489]35
[325]36   typedef enum { NETCDF4 = 0 } XFileType;
[489]37
[345]38   typedef xios::CContext * XContextPtr;
[325]39
40   // -------------------- Traitement des données ------------------------------
41   void cxios_init_server(void)
42   {
[489]43     CXios::initServerSide();
[325]44   }
45
46   void cxios_init_client(const char * client_id , int len_client_id, MPI_Fint* f_local_comm, MPI_Fint* f_return_comm )
47   {
[489]48      std::string str;
[325]49      MPI_Comm local_comm ;
50      MPI_Comm return_comm ;
[489]51
[325]52      if (!cstr2string(client_id, len_client_id, str)) return;
[347]53
[325]54      int initialized ;
55      MPI_Initialized(&initialized) ;
56      if (initialized) local_comm=MPI_Comm_f2c(*f_local_comm) ;
57      else local_comm=MPI_COMM_NULL ;
58      CXios::initClientSide(str,local_comm,return_comm);
59      *f_return_comm=MPI_Comm_c2f(return_comm) ;
[361]60      CTimer::get("XIOS init").suspend() ;
61      CTimer::get("XIOS").suspend() ;
[325]62   }
63
64   void cxios_context_initialize(const char * context_id , int len_context_id, MPI_Fint* f_comm)
65   {
[489]66     std::string str;
[325]67     MPI_Comm comm ;
[489]68
[325]69     if (!cstr2string(context_id, len_context_id, str)) return;
[347]70     CTimer::get("XIOS").resume() ;
71     CTimer::get("XIOS init context").resume() ;
[325]72     comm=MPI_Comm_f2c(*f_comm) ;
[342]73     CClient::registerContext(str,comm) ;
[347]74     CTimer::get("XIOS init context").suspend() ;
75     CTimer::get("XIOS").suspend() ;
[325]76   }
[489]77
[461]78   void cxios_context_is_initialized(const char * context_id , int len_context_id, bool* initialized)
79   {
[489]80     std::string str;
81
[461]82     if (!cstr2string(context_id, len_context_id, str)) return;
83     CTimer::get("XIOS").resume() ;
84     CContext* context = CContext::get(str,str) ;
85     *initialized=context->isInitialized() ;
86     CTimer::get("XIOS").suspend() ;
[489]87   }
88
[325]89    void cxios_context_close_definition()
90   {
[347]91     CTimer::get("XIOS").resume() ;
92     CTimer::get("XIOS close definition").resume() ;
93     CContext* context = CContext::getCurrent() ;
[325]94     context->closeDefinition() ;
[347]95     CTimer::get("XIOS close definition").suspend() ;
96     CTimer::get("XIOS").suspend() ;
[489]97   }
[325]98
99   void cxios_context_finalize()
100   {
[347]101     CTimer::get("XIOS").resume() ;
102     CTimer::get("XIOS context finalize").resume() ;
103     CContext* context = CContext::getCurrent() ;
[325]104     context->finalize() ;
[347]105     CTimer::get("XIOS context finalize").suspend() ;
106     CTimer::get("XIOS").suspend() ;
[325]107   }
[489]108
[325]109   void cxios_finalize()
110   {
[347]111     CTimer::get("XIOS").resume() ;
112     CTimer::get("XIOS finalize").resume() ;
[325]113     CXios::clientFinalize() ;
114   }
115
[445]116   void cxios_solve_inheritance()
117   {
118     CTimer::get("XIOS").resume() ;
119     CContext* context = CContext::getCurrent() ;
120     context->solveAllInheritance(false) ;
121     CTimer::get("XIOS").suspend() ;
[489]122   }
123
124   /*! \brief This group of functions retrieve variable information from the configuration file (.xml)
125    *
126    * These functions provide intermediate C interfaces to get variable information of the configuration file (e.x iodef.xml),
127    * from a Fortran one, for example the value of a variable with id = "using_server".
128    * Each function corresponds to each basic type.
129    * \param varId        [in] id of the variable that we'd like to get
130    * \param varIdSize    [in] size of the variable type (integer, float, double, string)
131    * \param dataInt      [in/out] the retrieved data
132    * \param isVarExisted [in/out] Verify whether variable with varId exists
133   */
134   void cxios_get_variable_data_k8(const char * varId, int varIdSize, double * data, bool * isVarExisted)
135   {
136      std::string varIdStr;
137      if (!cstr2string(varId, varIdSize, varIdStr)) return;
138
139      CTimer::get("XIOS").resume();
140      CTimer::get("XIOS get variable data").resume();
141
142      CContext* context = CContext::getCurrent();
143      *isVarExisted = CVariable::has(context->getId(), varIdStr);
144
145      if (*isVarExisted)
146      {
147        *data = CVariable::get(context->getId(),varIdStr)->getData<double>();
148      }
149
150      CTimer::get("XIOS get variable data").suspend() ;
151      CTimer::get("XIOS").suspend() ;
152   }
153
154   void cxios_get_variable_data_k4(const char * varId, int varIdSize, float * data, bool * isVarExisted)
155   {
156      std::string varIdStr;
157      if (!cstr2string(varId, varIdSize, varIdStr)) return;
158
159      CTimer::get("XIOS").resume();
160      CTimer::get("XIOS get variable data").resume();
161
162      CContext* context = CContext::getCurrent();
163      *isVarExisted = CVariable::has(context->getId(), varIdStr);
164
165      if (*isVarExisted)
166      {
167        *data = CVariable::get(context->getId(),varIdStr)->getData<float>();
168      }
169
170      CTimer::get("XIOS get variable data").suspend() ;
171      CTimer::get("XIOS").suspend() ;
172   }
173
174   void cxios_get_variable_data_int(const char * varId, int varIdSize, int * data, bool * isVarExisted)
175   {
176      std::string varIdStr;
177      if (!cstr2string(varId, varIdSize, varIdStr)) return;
178
179      CTimer::get("XIOS").resume();
180      CTimer::get("XIOS get variable data").resume();
181
182      CContext* context = CContext::getCurrent();
183      *isVarExisted = CVariable::has(context->getId(), varIdStr);
184
185      if (*isVarExisted)
186      {
187        *data = CVariable::get(context->getId(),varIdStr)->getData<int>();
188      }
189
190      CTimer::get("XIOS get variable data").suspend() ;
191      CTimer::get("XIOS").suspend() ;
192   }
193
194   void cxios_get_variable_data_logic(const char * varId, int varIdSize, bool * data, bool * isVarExisted)
195   {
196      std::string varIdStr;
197      if (!cstr2string(varId, varIdSize, varIdStr)) return;
198
199      CTimer::get("XIOS").resume();
200      CTimer::get("XIOS get variable data").resume();
201
202      CContext* context = CContext::getCurrent();
203      *isVarExisted = CVariable::has(context->getId(), varIdStr);
204
205      if (*isVarExisted)
206      {
207        *data = CVariable::get(context->getId(),varIdStr)->getData<bool>();
208      }
209
210      CTimer::get("XIOS get variable data").suspend() ;
211      CTimer::get("XIOS").suspend() ;
212   }
213
214   void cxios_get_variable_data_char(const char * varId, int varIdSize, char * data, int dataSizeIn, bool * isVarExisted)
215   {
216      std::string varIdStr;
217      if (!cstr2string(varId, varIdSize, varIdStr)) return;
218
219      CTimer::get("XIOS").resume();
220      CTimer::get("XIOS get variable data").resume();
221
222      CContext* context = CContext::getCurrent();
223      *isVarExisted = CVariable::has(context->getId(), varIdStr);
224
225      if (*isVarExisted)
226      {
227        int dataSizeOut = CVariable::get(context->getId(),varIdStr)->getData<string>().length();
228        strncpy(data, CVariable::get(context->getId(),varIdStr)->getData<string>().c_str(), std::min(dataSizeIn, dataSizeOut));
229      }
230
231      CTimer::get("XIOS get variable data").suspend() ;
232      CTimer::get("XIOS").suspend() ;
233   }
234
235   /*! \brief This group of functions write information into existing variable in the configuration file (.xml)
236    *
237    *  These functions provide intermediate C interfaces to get variable information of the configuration file (e.x iodef.xml),
238    * from a Fortran one, for example the value of a variable with id = "using_server".
239    * Each function corresponds to each basic type.
240    * \param varId        [in] id of the variable that we'd like to get
241    * \param varIdSize    [in] size of the variable type (integer, float, double, string)
242    * \param data         [in] the input data
243    * \param isVarExisted [in/out] Verify whether variable with varId exists
244   */
245   void cxios_set_variable_data_k8(const char * varId, int varIdSize, double data, bool * isVarExisted)
246   {
247      std::string varIdStr;
248      if (!cstr2string(varId, varIdSize, varIdStr)) return;
249
250      CTimer::get("XIOS").resume();
251      CTimer::get("XIOS set variable data").resume();
252
253      CContext* context = CContext::getCurrent() ;
254      *isVarExisted = CVariable::has(context->getId(), varIdStr);
255
256      if (*isVarExisted)
257      {
258        CVariable::get(context->getId(),varIdStr)->setData<double>(data);
259        CVariable::get(context->getId(),varIdStr)->sendValue();
260      }
261
262      CTimer::get("XIOS set variable data").suspend() ;
263      CTimer::get("XIOS").suspend() ;
264   }
265
266   void cxios_set_variable_data_k4(const char * varId, int varIdSize, float data, bool * isVarExisted)
267   {
268      std::string varIdStr;
269      if (!cstr2string(varId, varIdSize, varIdStr)) return;
270
271      CTimer::get("XIOS").resume();
272      CTimer::get("XIOS set variable data").resume();
273
274      CContext* context = CContext::getCurrent() ;
275      *isVarExisted = CVariable::has(context->getId(), varIdStr);
276
277      if (*isVarExisted)
278      {
279        CVariable::get(context->getId(),varIdStr)->setData<float>(data);
280        CVariable::get(context->getId(),varIdStr)->sendValue();
281      }
282
283      CTimer::get("XIOS set variable data").suspend() ;
284      CTimer::get("XIOS").suspend() ;
285   }
286
287   void cxios_set_variable_data_int(const char * varId, int varIdSize, int data, bool * isVarExisted)
288   {
289      std::string varIdStr;
290      if (!cstr2string(varId, varIdSize, varIdStr)) return;
291
292      CTimer::get("XIOS").resume();
293      CTimer::get("XIOS set variable data").resume();
294
295      CContext* context = CContext::getCurrent() ;
296      *isVarExisted = CVariable::has(context->getId(), varIdStr);
297
298      if (*isVarExisted)
299      {
300        CVariable::get(context->getId(),varIdStr)->setData<int>(data);
301        CVariable::get(context->getId(),varIdStr)->sendValue();
302      }
303
304
305      CTimer::get("XIOS set variable data").suspend() ;
306      CTimer::get("XIOS").suspend() ;
307   }
308
309   void cxios_set_variable_data_logic(const char * varId, int varIdSize, bool data, bool * isVarExisted)
310   {
311      std::string varIdStr;
312      if (!cstr2string(varId, varIdSize, varIdStr)) return;
313
314      CTimer::get("XIOS").resume();
315      CTimer::get("XIOS set variable data").resume();
316
317      CContext* context = CContext::getCurrent() ;
318      *isVarExisted = CVariable::has(context->getId(), varIdStr);
319
320      if (*isVarExisted)
321      {
322        CVariable::get(context->getId(),varIdStr)->setData<bool>(data);
323        CVariable::get(context->getId(),varIdStr)->sendValue();
324      }
325
326      CTimer::get("XIOS set variable data").suspend() ;
327      CTimer::get("XIOS").suspend() ;
328   }
329
330   void cxios_set_variable_data_char(const char * varId, int varIdSize, const char * data, int dataSizeIn, bool * isVarExisted)
331   {
332      std::string varIdStr, dataStr;
333      if (!cstr2string(varId, varIdSize, varIdStr)) return;
334      if (!cstr2string(data, dataSizeIn, dataStr))
335      {
336        *isVarExisted = false;
337        return;
338      }
339
340      CTimer::get("XIOS").resume();
341      CTimer::get("XIOS set variable data").resume();
342
343      CContext* context = CContext::getCurrent() ;
344      *isVarExisted = CVariable::has(context->getId(), varIdStr);
345
346      if (*isVarExisted)
347      {
348        CVariable::get(context->getId(),varIdStr)->setData<string>(dataStr);
349        CVariable::get(context->getId(),varIdStr)->sendValue();
350      }
351
352      CTimer::get("XIOS set variable data").suspend() ;
353      CTimer::get("XIOS").suspend() ;
354   }
355
356
[325]357   // ---------------------- Ecriture des données ------------------------------
[489]358
[325]359   void cxios_write_data_k81(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize)
360   {
361      std::string fieldid_str;
[489]362      if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
363
[347]364      CTimer::get("XIOS").resume() ;
365      CTimer::get("XIOS send field").resume() ;
366      CContext* context = CContext::getCurrent() ;
[403]367      if (!context->hasServer) context->client->checkBuffers() ;
[369]368      CArray<double,(StdSize)1> data(data_k8,shape(data_Xsize),neverDeleteData) ;
[325]369      CField::get(fieldid_str)->setData(data) ;
[369]370      CField toto ;
371      toto.setData(data) ;
[347]372      CTimer::get("XIOS send field").suspend() ;
373      CTimer::get("XIOS").suspend() ;
[325]374   }
[489]375
[325]376   void cxios_write_data_k82(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize, int data_Ysize)
377   {
378      std::string fieldid_str;
379      if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
[489]380
[347]381      CTimer::get("XIOS").resume() ;
382      CTimer::get("XIOS send field").resume() ;
383      CContext* context = CContext::getCurrent() ;
[403]384      if (!context->hasServer) context->client->checkBuffers() ;
[489]385
[369]386      CArray<double,2>data(data_k8,shape(data_Xsize,data_Ysize),neverDeleteData) ;
[325]387      CField::get(fieldid_str)->setData(data) ;
[347]388      CTimer::get("XIOS send field").suspend() ;
389      CTimer::get("XIOS").suspend() ;
[325]390   }
[489]391
[325]392   void cxios_write_data_k83(const char * fieldid, int fieldid_size, double * data_k8, int data_Xsize, int data_Ysize, int data_Zsize)
393   {
394      std::string fieldid_str;
[489]395      if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
[347]396
397      CTimer::get("XIOS").resume() ;
398      CTimer::get("XIOS send field").resume() ;
399      CContext* context = CContext::getCurrent() ;
[403]400      if (!context->hasServer) context->client->checkBuffers() ;
[369]401
402      CArray<double,3>data(data_k8,shape(data_Xsize,data_Ysize,data_Zsize),neverDeleteData) ;
[325]403      CField::get(fieldid_str)->setData(data) ;
[347]404      CTimer::get("XIOS send field").suspend() ;
405      CTimer::get("XIOS").suspend() ;
[325]406   }
[489]407
[325]408   void cxios_write_data_k41(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize)
409   {
410      std::string fieldid_str;
[489]411     if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
[347]412
413      CTimer::get("XIOS").resume() ;
414      CTimer::get("XIOS send field").resume() ;
415      CContext* context = CContext::getCurrent() ;
[403]416      if (!context->hasServer) context->client->checkBuffers() ;
417
[369]418      CArray<float,1> data_tmp(data_k4,shape(data_Xsize),neverDeleteData) ;
419      CArray<double,1> data(data_Xsize) ;
420      data=data_tmp ;
[325]421      CField::get(fieldid_str)->setData(data) ;
[347]422      CTimer::get("XIOS send field").suspend() ;
423      CTimer::get("XIOS").suspend() ;
[325]424   }
[489]425
[325]426   void cxios_write_data_k42(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize, int data_Ysize)
427   {
428      std::string fieldid_str;
[489]429      if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
[347]430
431      CTimer::get("XIOS").resume() ;
432      CTimer::get("XIOS send field").resume() ;
433      CContext* context = CContext::getCurrent() ;
[403]434      if (!context->hasServer) context->client->checkBuffers() ;
435
[369]436      CArray<float,2> data_tmp(data_k4,shape(data_Xsize,data_Ysize),neverDeleteData) ;
437      CArray<double,2> data(data_Xsize,data_Ysize) ;
438      data=data_tmp ;
[325]439      CField::get(fieldid_str)->setData(data) ;
[347]440      CTimer::get("XIOS send field").suspend() ;
441      CTimer::get("XIOS").suspend() ;
[325]442   }
[489]443
[325]444   void cxios_write_data_k43(const char * fieldid, int fieldid_size, float * data_k4, int data_Xsize, int data_Ysize, int data_Zsize)
445   {
446      std::string fieldid_str;
[489]447
448      if (!cstr2string(fieldid, fieldid_size, fieldid_str)) return;
449
[347]450      CTimer::get("XIOS").resume() ;
451      CTimer::get("XIOS send field").resume() ;
452      CContext* context = CContext::getCurrent() ;
[403]453      if (!context->hasServer) context->client->checkBuffers() ;
[369]454
455      CArray<float,3> data_tmp(data_k4,shape(data_Xsize,data_Ysize,data_Zsize),neverDeleteData) ;
456      CArray<double,3> data(data_Xsize,data_Ysize,data_Zsize) ;
457      data=data_tmp ;
[489]458
[325]459      CField::get(fieldid_str)->setData(data) ;
[347]460      CTimer::get("XIOS send field").suspend() ;
461      CTimer::get("XIOS").suspend() ;
462
[489]463    }
[325]464
465} // extern "C"
Note: See TracBrowser for help on using the repository browser.