FasTensor  1.0.0
Transform Supercomputing for AI
ft_array.h
Go to the documentation of this file.
1 /*
2 ****************************
3 
4 FasTensor (FT) Copyright (c) 2021, The Regents of the University of
5 California, through Lawrence Berkeley National Laboratory (subject to
6 receipt of any required approvals from the U.S. Dept. of Energy).
7 All rights reserved.
8 
9 If you have questions about your rights to use or distribute this software,
10 please contact Berkeley Lab's Intellectual Property Office at
12 
13 NOTICE. This Software was developed under funding from the U.S. Department
14 of Energy and the U.S. Government consequently retains certain rights. As
15 such, the U.S. Government has been granted for itself and others acting on
16 its behalf a paid-up, nonexclusive, irrevocable, worldwide license in the
17 Software to reproduce, distribute copies to the public, prepare derivative
18 works, and perform publicly and display publicly, and to permit others to do so.
19 
20 
21 ****************************
22 
23 
24 *** License Agreement ***
25 
26 FasTensor (FT) Copyright (c) 2021, The Regents of the University of
27 California, through Lawrence Berkeley National Laboratory (subject to
28 receipt of any required approvals from the U.S. Dept. of Energy).
29 All rights reserved.
30 
31 Redistribution and use in source and binary forms, with or without
32 modification, are permitted provided that the following conditions are met:
33 
34 (1) Redistributions of source code must retain the above copyright notice,
35 this list of conditions and the following disclaimer.
36 
37 (2) Redistributions in binary form must reproduce the above copyright
38 notice, this list of conditions and the following disclaimer in the
39 documentation and/or other materials provided with the distribution.
40 
41 (3) Neither the name of the University of California, Lawrence Berkeley
42 National Laboratory, U.S. Dept. of Energy nor the names of its contributors
43 may be used to endorse or promote products derived from this software
44 without specific prior written permission.
45 
46 
47 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 POSSIBILITY OF SUCH DAMAGE.
58 
59 You are under no obligation whatsoever to provide any bug fixes, patches,
60 or upgrades to the features, functionality or performance of the source
61 code ("Enhancements") to anyone; however, if you choose to make your
62 Enhancements available either publicly, or directly to Lawrence Berkeley
63 National Laboratory, without imposing a separate written license agreement
64 for such Enhancements, then you hereby grant the following license: a
65 non-exclusive, royalty-free perpetual license to install, use, modify,
66 prepare derivative works, incorporate into other computer software,
67 distribute, and sublicense such enhancements or derivative works thereof,
68 in binary and source code form.
69 */
70 
80 //see au.h for its definations
81 //extern int ft_size;
82 //extern int ft_rank;
83 extern int ft_size;
84 extern int ft_rank;
85 
86 #ifndef ARRAY_UDF_ARRAY_H
87 #define ARRAY_UDF_ARRAY_H
88 
89 #include <assert.h>
90 #include <stdarg.h>
91 #include <regex>
92 #include "mpi.h"
93 #include "ft_endpoint.h"
94 #include "ft_stencil.h"
95 #include "ft_utility.h"
96 #include "ft_type.h"
97 #include "ft_endpoint_factory.h"
98 #include "ft_mpi.h"
99 #include "ft_merge.h"
100 #include "ft_output_vector.h"
101 #include "ft_vis.h"
102 #include "ft_array_transpose.h"
103 
104 // std::vector<Endpoint *> endpoint_clean_vector;
105 //extern std::map<Endpoint *, bool> endpoint_clean_vector;
106 
107 //#define AU_DEFAULT_CHUNK_SIZE_PER_DIM 1000
108 //extern std::map<Endpoint *, bool> endpoint_clean_vector;
109 
110 extern std::vector<Endpoint *> endpoint_to_clean_vector;
111 
112 namespace FT
113 {
114 
120 #define TRANSFORM(A_BASE_OBJECT, UDF, B, A_TYPE, UDF_OUT_TYPE) \
121  { \
122  switch (A_TYPE) \
123  { \
124  case AuEndpointDataType::AU_SHORT: \
125  static_cast<FT::Array<short> *>(A_BASE_OBJECT)->Transform<UDF_OUT_TYPE>(UDF, B); \
126  break; \
127  case AuEndpointDataType::AU_DOUBLE: \
128  static_cast<FT::Array<double> *>(A_BASE_OBJECT)->Transform<UDF_OUT_TYPE>(UDF, B); \
129  break; \
130  case AuEndpointDataType::AU_FLOAT: \
131  static_cast<FT::Array<float> *>(A_BASE_OBJECT)->Transform<UDF_OUT_TYPE>(UDF, B); \
132  break; \
133  case AuEndpointDataType::AU_INT: \
134  static_cast<FT::Array<int> *>(A_BASE_OBJECT)->Transform<UDF_OUT_TYPE>(UDF, B); \
135  break; \
136  default: \
137  AU_EXIT("Not supported type yet in TRANSFORM macro !"); \
138  } \
139  }
140 
145  class ArrayBase
146  {
147  public:
148  virtual int EnableApplyStride(const std::vector<int> &skip_size_p) = 0;
149  virtual void SetVectorDirection(OutputVectorFlatDirection flat_direction_index) = 0;
150  virtual void ReportCost() = 0;
151  virtual int ControlEndpoint(int cmd_p) = 0;
152  virtual int ControlEndpoint(int cmd_p, std::vector<std::string> &arg_v_p) = 0;
153  virtual int SetChunkSize(std::vector<int> data_chunk_size_p) = 0;
154  virtual int SetOverlapSize(const vector<int> os_p) = 0;
155  virtual int GetArraySize(std::vector<unsigned long long> &size_p) = 0;
156  virtual int GetStencilTag() = 0;
157  virtual int GetTag(const std::string &name, std::string &value) = 0;
158  virtual ~ArrayBase() = default;
159  };
160 
161  template <class T>
162  class Array : public ArrayBase
163  {
164  private:
176  std::string array_data_endpoint_info;
177  Endpoint *endpoint = NULL;
178 
179  //Below are info about endpooint
180  int data_dims; //The number of dimensioins of data in endpoint
181  std::vector<unsigned long long> data_size; //The size of each dimension (global, extracted from data of endpoint
182  std::vector<int> data_chunk_size; //size of each chunk (user provide)
183  std::vector<int> data_overlap_size; //size of overlapping (user provide)
184  std::vector<unsigned long long> data_chunked_size; //The number of chunks per dimenstion
185  int data_auto_chunk_dim_index;
186  unsigned long long data_total_chunks; //The total number of chunks (global)
187 
188  std::vector<unsigned long long> current_chunk_start_offset; //Start offset on disk
189  std::vector<unsigned long long> current_chunk_end_offset; //End offset on disk
190  std::vector<unsigned long long> current_chunk_size; //Size of the chunk, euqal to end_offset - start_offset
191  unsigned long long current_chunk_cells; //The number of cells in current chunk
192 
193  std::vector<unsigned long long> current_result_chunk_start_offset; //Start offset on disk
194  std::vector<unsigned long long> current_result_chunk_end_offset; //End offset on disk
195  unsigned long long current_result_chunk_cells; //The number of cells in current chunk
196 
197  std::vector<unsigned long long> current_chunk_ol_start_offset; //Start offset on disk with overlapping
198  std::vector<unsigned long long> current_chunk_ol_end_offset; //End offset on disk with overlapping
199  std::vector<unsigned long long> current_chunk_ol_size; //Size of the chunk, euqal to end_offset - start_offset
200  unsigned long long current_chunk_ol_cells; //The number of cells in current chunk
201 
202  unsigned long long current_chunk_id; //Id of the current chunk (in memory) to apply UDF
203  unsigned long long prev_chunk_id; //for SetChunkID of CellTarget
204  std::vector<int> skip_size; //Size to ship after each operation
205  std::vector<unsigned long long> skiped_dims_size; //Size of the data after skip
206  std::vector<unsigned long long> skiped_chunks; //# of chunks after skip
207  std::vector<int> skiped_chunk_size; //Size of each chunk after skip
208 
209  std::vector<T> current_chunk_data; //Pointer to data of current chunk
210 
211  std::vector<long long> ol_origin_offset; //Size of the chunk, euqal to end_offset - start_offset
212 
213  std::vector<unsigned long long> view_start_offset;
214  std::vector<unsigned long long> view_size;
215  std::vector<unsigned long long> view_orginal_data_dims_size;
216 
217  std::vector<T> mirror_values;
218 
219  OutputVectorFlatDirection output_vector_flat_direction_index;
220 
221  std::vector<size_t> output_vector_flat_shape;
222 
223  std::vector<std::string> attribute_array_data_endpoint_info;
224 
225  std::vector<Endpoint *> attribute_endpoint_vector; //vector of endpoints for a virtual array
226 
227  //For directory
228  std::regex dir_input_regex, dir_output_regex;
229  std::string dir_output_replace_str;
230 
231  //For chunk operations
232  size_t set_chunk_size_by_mem_max_mem_size = 1073741824; //Byte, 1GB
233 
234  //Flag variable for different purposes
235  bool skip_flag = false;
236  bool view_flag = false;
237  bool cpp_vec_flag = false;
238  bool virtual_array_flag = false;
239  bool save_result_flag = true;
240  bool reverse_apply_direction_flag = false;
241  bool mirror_value_flag = false;
242  bool apply_replace_flag = false;
243  bool vector_type_flag = false;
244  bool endpoint_memory_flag = false;
245  bool has_padding_value_flag = false;
246  bool skip_not_aligned_w_array_flag = false;
247  bool is_the_last_chunk = false;
248  bool is_endpoint_created_flag = false;
249 
250  bool chunk_size_by_user_flag = false;
251  bool chunk_size_by_user_by_dimension_flag = false;
252  bool set_chunk_size_by_mem_flag = false;
253  bool set_overlap_size_by_auto_detection_flag = false;
254 
255  bool set_direct_output_flag = false;
256 
257  bool get_stencil_tag_flag = false;
258  std::map<std::string, std::string> stencil_metadata_map;
259 
260  bool has_output_stencil_tag_flag = false;
261  std::map<std::string, std::string> output_stencil_metadata_map;
262 
263  int skip_not_aligned_w_array_index;
264  //The shape of output_vector when vector_type_flag = true
265  std::vector<size_t> output_vector_shape;
266  std::vector<size_t> previous_output_vector_shape;
267  //float input_output_ratio; // the ratio = size of input / size of output, only valid along output_vector_shape
268  //padding_value_p
269  T padding_value;
270 
271  //help variable
272  AU_WTIME_TYPE t_start, time_read = 0, time_udf = 0, time_write = 0, time_create = 0, time_sync = 0, time_nonvolatile = 0;
273 
274  public:
279  Array(){
280 
281  };
282 
283  //Below are three constructors for file based constructor
284 
293  Array(std::string data_endpoint)
294  {
295  array_data_endpoint_info = data_endpoint;
296  endpoint = EndpointFactory::NewEndpoint(data_endpoint);
297  AuEndpointDataType data_element_type = InferDataType<T>();
298  endpoint->SetDataElementType(data_element_type);
299 
300  if (endpoint->GetEndpointType() == EP_MEMORY)
301  endpoint_memory_flag = true;
302  //endpoint_clean_vector[endpoint] = true;
303  endpoint_to_clean_vector.push_back(endpoint);
304  }
305 
313  Array(std::string data_endpoint, std::vector<int> cs)
314  {
315  array_data_endpoint_info = data_endpoint;
316  data_chunk_size = cs;
317  data_overlap_size.resize(cs.size());
318  std::fill(data_overlap_size.begin(), data_overlap_size.end(), 0);
319 
320  endpoint = EndpointFactory::NewEndpoint(data_endpoint);
321 
322  AuEndpointDataType data_element_type = InferDataType<T>();
323  endpoint->SetDataElementType(data_element_type);
324 
325  chunk_size_by_user_flag = true;
326  if (endpoint->GetEndpointType() == EP_MEMORY)
327  endpoint_memory_flag = true;
328 
329  //endpoint_clean_vector.push_back(endpoint);
330  //endpoint_clean_vector[endpoint] = true;
331  endpoint_to_clean_vector.push_back(endpoint);
332  }
333 
341  Array(std::string data_endpoint, std::vector<int> cs, std::vector<int> os)
342  {
343  array_data_endpoint_info = data_endpoint;
344  data_chunk_size = cs;
345  data_overlap_size = os;
346  endpoint = EndpointFactory::NewEndpoint(data_endpoint);
347 
348  AuEndpointDataType data_element_type = InferDataType<T>();
349  endpoint->SetDataElementType(data_element_type);
350 
351  chunk_size_by_user_flag = true;
352  if (endpoint->GetEndpointType() == EP_MEMORY)
353  endpoint_memory_flag = true;
354 
355  //endpoint_clean_vector.push_back(endpoint);
356  //endpoint_clean_vector[endpoint] = true;
357  endpoint_to_clean_vector.push_back(endpoint);
358  }
359 
366  Array(std::string data_endpoint, int auto_chunk_dim_index)
367  {
368  array_data_endpoint_info = data_endpoint;
369  data_auto_chunk_dim_index = auto_chunk_dim_index;
370  endpoint = EndpointFactory::NewEndpoint(data_endpoint);
371  //std::cout << data_endpoint << "\n";
372  AuEndpointDataType data_element_type = InferDataType<T>();
373  endpoint->SetDataElementType(data_element_type);
374  chunk_size_by_user_by_dimension_flag = true;
375  if (endpoint->GetEndpointType() == EP_MEMORY)
376  endpoint_memory_flag = true;
377 
378  //endpoint_clean_vector[endpoint] = true;
379  endpoint_to_clean_vector.push_back(endpoint);
380  }
381 
389  Array(std::string data_endpoint, std::vector<unsigned long long> size_p)
390  {
391  array_data_endpoint_info = data_endpoint;
392  endpoint = EndpointFactory::NewEndpoint(data_endpoint);
393  AuEndpointDataType data_element_type = InferDataType<T>();
394  endpoint->SetDataElementType(data_element_type);
395  endpoint->SetDimensions(size_p);
396 
397  if (endpoint->GetEndpointType() == EP_MEMORY)
398  {
399  endpoint_memory_flag = true;
400  endpoint->Create();
401  }
402 
403  data_size = size_p;
404  //endpoint_clean_vector[endpoint] = true;
405  endpoint_to_clean_vector.push_back(endpoint);
406  }
407 
414  Array(std::vector<int> cs, std::vector<int> os)
415  {
416  data_chunk_size = cs;
417  data_overlap_size = os;
418  }
419 
420  Array(std::vector<int> cs)
421  {
422  data_chunk_size = cs;
423  data_overlap_size.resize(cs.size());
424  std::fill(data_overlap_size.begin(), data_overlap_size.end(), 0);
425  }
431  Array(std::vector<T> &data_vector_endpoint)
432  {
433  }
434 
442  Array(std::vector<T> &data_vector_endpoint, std::vector<int> cs, std::vector<int> os)
443  {
444  }
445 
452  {
453  //endpoint_clean_vector[endpoint] = false;
454  //if (endpoint != NULL)
455  // delete endpoint;
456  //endpoint = NULL;
457  }
458 
467  {
468  //partition by dimensions
469  if (chunk_size_by_user_by_dimension_flag)
470  {
471  //data_chunked_size.resize(data_dims);
472  data_chunk_size.resize(data_dims);
473  //overlap_size_p.resize(data_dims);
474  for (int i = 0; i < data_dims; i++)
475  {
476  if (data_auto_chunk_dim_index == i)
477  {
478  if (data_size[i] % ft_size == 0)
479  {
480  data_chunk_size[i] = data_size[i] / ft_size;
481  }
482  else
483  {
484  data_chunk_size[i] = data_size[i] / ft_size + 1;
485  }
486  }
487  else
488  {
489  data_chunk_size[i] = data_size[i];
490  }
491  //data_overlap_size[i] = 0;
492  }
493 
494  return;
495  }
496 
497  if (set_chunk_size_by_mem_flag)
498  {
499  unsigned long long total_elements = 1;
500  for (int i = 0; i < data_dims; i++)
501  {
502  total_elements = data_size[i] * total_elements;
503  }
504  total_elements = total_elements / ft_size;
505  if (total_elements > (set_chunk_size_by_mem_max_mem_size / sizeof(T)))
506  {
507  total_elements = set_chunk_size_by_mem_max_mem_size / sizeof(T);
508  }
509  std::vector<unsigned long long> chunk_size_temp = RowMajorOrderReverse(total_elements, data_size);
510  int replace_flag = 1;
511  for (int i = data_dims - 1; i > 0; i--)
512  {
513  if (chunk_size_temp[i] != data_size[i])
514  {
515  chunk_size_temp[i] = data_size[i];
516  if (chunk_size_temp[i - 1] != 0)
517  {
518  chunk_size_temp[i - 1] = chunk_size_temp[i - 1] - 1;
519  }
520  else
521  {
522  replace_flag = 0;
523  break;
524  }
525  }
526  }
527 
528  for (int i = data_dims - 1; i >= 0; i--)
529  {
530  if (chunk_size_temp[i] == 0)
531  replace_flag = 0;
532  }
533 
534  if (replace_flag)
535  {
536  //unsigned long long to int here
537  for (int i = 0; i < data_dims; i++)
538  data_chunk_size[i] = chunk_size_temp[i];
539  }
540  else
541  {
542  AU_EXIT("SetChunkSizeByMem failed ! Please try specify the chunk size via SetChunkSize !");
543  }
544  return;
545  }
546 
547  if (endpoint != NULL && endpoint->GetEndpointType() == EP_DIR)
548  {
549  //chunk_size_p = endpoint->GetChunkSize();
550  }
551  //optimal chunk_size
552  }
553 
554  inline int SetOverlapSize(const vector<int> os_p)
555  {
556  data_overlap_size = os_p;
557  return 0;
558  }
560  {
561  set_overlap_size_by_auto_detection_flag = true;
562  return 0;
563  }
564  inline int GetOverlapSize(vector<int> &os_p)
565  {
566  os_p = data_overlap_size;
567  return 0;
568  }
569  inline int SetOverlapPadding(const T &padding_value_p)
570  {
571  has_padding_value_flag = true;
572  padding_value = padding_value_p;
573  return 0;
574  }
575 
576  inline int SyncOverlap()
577  {
578  if (endpoint != NULL)
579  {
580  if (endpoint->GetEndpointType() == EP_MEMORY)
581  {
582  std::vector<std::string> arg_v;
583  return endpoint->Control(MEMORY_SYNC_OVERLAP, arg_v);
584  }
585  return 0;
586  }
587 
588  return 0;
589  }
590 
591  template <class UDFOutputType>
593  {
594  if (endpoint != NULL)
595  {
596  if (endpoint->GetEndpointType() == EP_DIR || chunk_size_by_user_by_dimension_flag)
597  {
598  data_overlap_size.resize(data_dims);
599  for (int i = 0; i < data_dims; i++)
600  {
601  data_overlap_size[i] = 0;
602  }
603  }
604  return 0;
605  }
606 
607  if (set_overlap_size_by_auto_detection_flag)
608  {
609  std::vector<T> trail_data;
610  trail_data.resize(1);
611  Stencil<T> trail_cell(data_dims, &trail_data[0]);
612  UDF(trail_cell);
613  trail_cell.GetTrailRunResult(data_overlap_size);
614  }
615  //optimal overlap size
616  return 0;
617  }
618 
619  template <class UDFOutputType>
621  {
622  //Read the metadata (rank, dimension size) from endpoint
623  if (virtual_array_flag && attribute_endpoint_vector.size() >= 1)
624  {
625  //Get the data_size from first attribute
626  attribute_endpoint_vector[0]->ExtractMeta();
627  data_size = attribute_endpoint_vector[0]->GetDimensions();
628  data_dims = data_size.size();
629  for (int i = 1; i < attribute_endpoint_vector.size(); i++)
630  {
631  attribute_endpoint_vector[i]->ExtractMeta();
632  std::vector<unsigned long long> data_size_p = attribute_endpoint_vector[i]->GetDimensions();
633 
634  if (data_size != data_size_p)
635  {
636  AU_EXIT("All attributes must have same size");
637  }
638  }
639  }
640  else
641  {
642  endpoint->ExtractMeta();
643  data_size = endpoint->GetDimensions();
644  data_dims = data_size.size();
645  }
646 
647  UpdateChunkSize();
648  UpdateOverlapSize(UDF);
649 
650  //PrintVector("data_chunk_size: ", data_chunk_size);
651  //PrintVector("data_size: ", data_size);
652 
653  current_chunk_start_offset.resize(data_dims);
654  current_chunk_end_offset.resize(data_dims);
655  current_chunk_size.resize(data_dims);
656 
657  current_result_chunk_start_offset.resize(data_dims);
658  current_result_chunk_end_offset.resize(data_dims);
659 
660  current_chunk_ol_start_offset.resize(data_dims);
661  current_chunk_ol_end_offset.resize(data_dims);
662  current_chunk_ol_size.resize(data_dims);
663 
664  data_chunked_size.resize(data_dims);
665  ol_origin_offset.resize(data_dims);
666 
667  data_total_chunks = 1;
668 
669  for (int i = 0; i < data_dims; i++)
670  {
671  if (data_size[i] % data_chunk_size[i] == 0)
672  {
673  data_chunked_size[i] = data_size[i] / data_chunk_size[i];
674  }
675  else
676  {
677  data_chunked_size[i] = data_size[i] / data_chunk_size[i] + 1;
678  }
679  data_total_chunks = data_total_chunks * data_chunked_size[i];
680  }
681 
682  if (skip_flag)
683  {
684  skiped_dims_size.resize(data_dims);
685  skiped_chunks.resize(data_dims);
686  skiped_chunk_size.resize(data_dims);
687 
688  for (int i = 0; i < data_dims; i++)
689  {
690 
691  /*if (data_size[i] % skip_size[i] != 0 || data_chunk_size[i] % skip_size[i] != 0)
692  {
693  AU_EXIT("Strip size must be aligned with size of both array and chunk ! \n");
694  }*/
695 
696  if (data_chunk_size[i] % skip_size[i] != 0)
697  {
698  AU_EXIT("Strip size must be aligned with the size of chunk ! \n");
699  }
700 
701  if (data_size[i] % skip_size[i] != 0)
702  {
703  skip_not_aligned_w_array_flag = true;
704  skip_not_aligned_w_array_index = i;
705  skiped_dims_size[i] = data_size[i] / skip_size[i] + 1;
706  }
707  else
708  {
709  skiped_dims_size[i] = data_size[i] / skip_size[i];
710  }
711 
712  skiped_chunk_size[i] = data_chunk_size[i] / skip_size[i];
713  if (skiped_dims_size[i] % skiped_chunk_size[i] != 0)
714  {
715  skiped_chunks[i] = skiped_dims_size[i] / skiped_chunk_size[i] + 1;
716  }
717  else
718  {
719  skiped_chunks[i] = skiped_dims_size[i] / skiped_chunk_size[i];
720  }
721  }
722  }
723 
724  current_chunk_id = ft_rank; //Each process deal with one chunk one time, starting from its rank
725 
726  //#ifdef DEBUG
727  if (ft_rank == 0)
728  {
729  if (!virtual_array_flag)
730  endpoint->PrintInfo();
731  PrintVector(" data size", data_size);
732  PrintVector(" chunk size", data_chunk_size);
733  PrintVector(" overlap size", data_overlap_size);
734  PrintScalar("current chunk id:", current_chunk_id);
735  PrintScalar(" total chunks", data_total_chunks);
736  }
737  }
738 
744  {
745  if (!virtual_array_flag)
746  {
747  endpoint->PrintInfo();
748  }
749  else
750  {
751  for (auto aep : attribute_endpoint_vector)
752  aep->PrintInfo();
753  }
754  }
755 
764  template <class UDFOutputType, class BType = UDFOutputType>
765  void Apply(Stencil<UDFOutputType> (*UDF)(const Stencil<T> &), Array<BType> *B = nullptr)
766  {
767  Transform(UDF, B);
768  }
769 
770  template <class UDFOutputType, class BType = UDFOutputType>
772  {
773  Transform(UDF, &B);
774  }
775  /*
776  template <class UDFOutputType>
777  void Transform(Stencil<UDFOutputType> (*UDF)(const Stencil<T> &))
778  {
779  Transform(UDF, nullptr);
780  }
781  */
782 
791  template <class UDFOutputType, class BType = UDFOutputType>
792  void Transform(Stencil<UDFOutputType> (*UDF)(const Stencil<T> &), Array<BType> *B = nullptr)
793  {
794  //Set up the input data for LoadNextChunk
796 
797  //reset timer to zero
798  time_read = 0;
799  time_write = 0;
800  time_udf = 0;
801 
802  std::vector<UDFOutputType> current_result_chunk_data;
803  unsigned long long current_result_chunk_data_size = 1;
804 
805  vector_type_flag = InferVectorType<UDFOutputType>();
806 
807  t_start = AU_WTIME;
808  int load_ret = LoadNextChunk(current_result_chunk_data_size);
809  current_result_chunk_data.resize(current_result_chunk_data_size);
810  time_read = time_read + (AU_WTIME - t_start);
811 
812  unsigned long long result_vector_index = 0;
813 
814  while (load_ret == 1)
815  {
816  unsigned long long cell_target_g_location_rm;
817  result_vector_index = 0;
818 
819  //unsigned long long lrm;
820  t_start = AU_WTIME;
821 
822 #if defined(_OPENMP)
823  size_t *prefix;
824 #endif
825 
826 #if defined(_OPENMP)
827 #pragma omp parallel
828 #endif
829  {
830  std::vector<unsigned long long> cell_coordinate(data_dims, 0), cell_coordinate_ol(data_dims, 0), global_cell_coordinate(data_dims, 0);
831  unsigned long long offset_ol;
832  Stencil<T> cell_target(0, &current_chunk_data[0], cell_coordinate_ol, current_chunk_ol_size, data_size);
833  if (has_padding_value_flag)
834  {
835  cell_target.SetPadding(padding_value);
836  }
837  cell_target.SetChunkID(prev_chunk_id);
838 
839  if (get_stencil_tag_flag)
840  {
841  cell_target.SetTagMap(stencil_metadata_map);
842  }
843  Stencil<UDFOutputType> cell_return_stencil;
844  UDFOutputType cell_return_value;
845  unsigned long long cell_target_g_location_rm;
846  int is_mirror_value = 0;
847  std::vector<unsigned long long> skip_chunk_coordinate(data_dims, 0), skip_chunk_coordinate_start(data_dims, 0);
848  int skip_flag_on_cell = 0;
849 
850 #if defined(_OPENMP)
851  int ithread = omp_get_thread_num();
852  int nthreads = omp_get_num_threads();
853 #pragma omp single
854  {
855  prefix = new size_t[nthreads + 1];
856  prefix[0] = 0;
857  }
858  std::vector<UDFOutputType> vec_private;
859 #endif
860 
861 #if defined(_OPENMP)
862 #pragma omp for schedule(static) nowait
863 #endif
864  for (unsigned long long i = 0; i < current_chunk_cells; i++)
865  {
866  ROW_MAJOR_ORDER_REVERSE_MACRO(i, current_chunk_size, current_chunk_size.size(), cell_coordinate)
867 
868  if (skip_flag == 1)
869  {
870  skip_flag_on_cell = 0;
871  for (int id = 0; id < data_dims; id++)
872  {
873  //The coordinate of the skip chunk this coordinate belong to
874  skip_chunk_coordinate[id] = std::floor(cell_coordinate[id] / skip_size[id]);
875  skip_chunk_coordinate_start[id] = skip_chunk_coordinate[id] * skip_size[id]; //first cell's coodinate of this skip chunk
876  if (skip_chunk_coordinate_start[id] != cell_coordinate[id])
877  { //we only run on the first element of this skip chunk
878  skip_flag_on_cell = 1;
879  break;
880  }
881  }
882 
883  if (skip_flag_on_cell == 1)
884  continue; // for (unsigned long long i = 0; i < current_chunk_cells; i++)
885  assert(i < current_chunk_cells);
886  }
887 
888  //Get the coodinate with overlapping
889  //Also, get the global coodinate of the cell in original array
890  for (int ii = 0; ii < data_dims; ii++)
891  {
892  if (cell_coordinate[ii] + ol_origin_offset[ii] < current_chunk_ol_size[ii])
893  {
894  cell_coordinate_ol[ii] = cell_coordinate[ii] + ol_origin_offset[ii];
895  }
896  else
897  {
898  cell_coordinate_ol[ii] = current_chunk_ol_size[ii] - 1;
899  }
900  //get the global coordinate
901  global_cell_coordinate[ii] = current_chunk_start_offset[ii] + cell_coordinate[ii];
902  }
903 
904  //Update the offset with overlapping
905  ROW_MAJOR_ORDER_MACRO(current_chunk_ol_size, current_chunk_ol_size.size(), cell_coordinate_ol, offset_ol);
906  if (endpoint != NULL && endpoint->GetEndpointType() != EP_DIR)
907  {
908  ROW_MAJOR_ORDER_MACRO(data_size, data_size.size(), global_cell_coordinate, cell_target_g_location_rm)
909  cell_target.SetLocation(offset_ol, cell_coordinate_ol, cell_coordinate, current_chunk_size, ol_origin_offset, current_chunk_ol_size, global_cell_coordinate, cell_target_g_location_rm);
910  }
911  else
912  {
913  cell_target.SetLocation(offset_ol, cell_coordinate_ol, cell_coordinate, current_chunk_size, ol_origin_offset, current_chunk_ol_size, cell_coordinate_ol, offset_ol);
914  }
915  //Set the global coodinate of the cell as the ID of the cell
916  //Disable it for performance.
917  //RowMajorOrder(data_dims_size, global_cell_coordinate)
918  //ROW_MAJOR_ORDER_MACRO(data_dims_size, data_dims_size.size(), global_cell_coordinate, cell_target_g_location_rm)
919  //cell_target.set_my_g_location_rm(cell_target_g_location_rm);
920 
921  cell_return_stencil = UDF(cell_target); // Called by C++
922  cell_return_value = cell_return_stencil.get_value();
923 
924  if (vector_type_flag == true)
925  {
926  cell_return_stencil.GetShape(output_vector_shape);
927  }
928 
929  if (cell_return_stencil.HasTagMap())
930  {
931  has_output_stencil_tag_flag = true;
932  cell_return_stencil.GetTagMap(output_stencil_metadata_map);
933  }
934 
935  if (save_result_flag)
936  {
937  if (skip_flag)
938  {
939 #if defined(_OPENMP)
940  vec_private.push_back(cell_return_value);
941 #else
942  current_result_chunk_data[result_vector_index] = cell_return_value;
943  result_vector_index = result_vector_index + 1;
944 #endif
945  //When skip_flag is set, there is no need to have apply_replace_flag
946  //Todo: in future
947  //if(apply_replace_flag == 1){
948  // current_chunk_data[i] = cell_return_value; //Replace the orginal data
949  //}
950  }
951  else
952  {
953  current_result_chunk_data[i] = cell_return_value; //cell_return = cell_return.
954  if (apply_replace_flag == 1)
955  {
956  std::memcpy(&current_chunk_data[offset_ol], &cell_return_value, sizeof(T));
957  }
958  }
959  }
960  } //end for loop, finish the processing on a single chunk in row-major direction
961 #if defined(_OPENMP)
962  prefix[ithread + 1] = vec_private.size();
963 #pragma omp barrier
964 #pragma omp single
965  {
966  for (int i = 1; i < (nthreads + 1); i++)
967  {
968  prefix[i] += prefix[i - 1];
969  }
970  if (current_result_chunk_data.size() != prefix[nthreads])
971  {
972  std::cout << "Wrong output size ! prefix[nthreads] =" << prefix[nthreads] << ", current.size() = " << current_result_chunk_data.size() << " \n ";
973  }
974  } //end of omp for
975  std::copy(vec_private.begin(), vec_private.end(), current_result_chunk_data.begin() + prefix[ithread]);
976  clear_vector(vec_private);
977 #endif
978  } //end of omp parallel
979 
980 #if defined(_OPENMP)
981  delete[] prefix;
982 #endif
983  time_udf = AU_WTIME - t_start + time_udf;
984 
986  //end of processing on a single chunk
988 
989  t_start = AU_WTIME;
990 
991  if (B != nullptr)
992  {
993 
994  std::vector<unsigned long long> B_data_size;
995  std::vector<int> B_data_chunk_size, B_data_overlap_size;
996 
997  if (B->GetEndpointType() == EP_DIR && GetEndpointType() == EP_DIR)
998  {
999  std::vector<std::string> dir_file_list = GetDirFile();
1000  B->SetDirFile(dir_file_list);
1001  std::vector<int> dir_chunk_size = GetDirChunkSize();
1002  B->SetDirChunkSize(dir_chunk_size);
1003  }
1004 
1005  if (vector_type_flag)
1006  {
1007  //output_vector_shape
1008  size_t vector_size;
1009  std::vector<unsigned long long> current_chunk_start_offset_v = current_result_chunk_start_offset, current_chunk_end_offset_v = current_result_chunk_end_offset;
1010  void *data_point;
1011  // data_point = FlatVector(current_result_chunk_data, output_vector_flat_direction_index, current_chunk_start_offset_v, current_chunk_end_offset_v, vector_size);
1012  // InferOutputSize(B_data_size, B_data_chunk_size, B_data_overlap_size, vector_size);
1013 
1014  if (is_the_last_chunk && (previous_output_vector_shape.size() == 0))
1015  {
1016  //int normal_chunk_output_size = data_chunk_size[i] / (current_chunk_ol_size[i] / output_vector_shape[i]);
1017  previous_output_vector_shape = output_vector_shape;
1018  for (int i = 0; i < output_vector_shape.size(); i++)
1019  {
1020  if (skip_not_aligned_w_array_flag && skip_not_aligned_w_array_index == i)
1021  {
1022  previous_output_vector_shape[i] = data_chunk_size[i] / (current_chunk_ol_size[i] / output_vector_shape[i]);
1023  }
1024  }
1025  }
1026  //PrintVector("Debug: output_vector_shape = ", output_vector_shape);
1027  //PrintVector("Debug: current_chunk_start_offset_v = ", current_chunk_start_offset_v);
1028  //PrintVector("Debug: current_chunk_end_offset_v = ", current_chunk_end_offset_v);
1029  //PrintVector("Debug: previous_output_vector_shape = ", previous_output_vector_shape);
1030 
1031  data_point = InsertOutputVV2WriteV(current_result_chunk_data, output_vector_shape, current_chunk_start_offset_v, current_chunk_end_offset_v, is_the_last_chunk, previous_output_vector_shape);
1032  CalculateOutputSize(B_data_size, B_data_chunk_size, B_data_overlap_size);
1033  //PrintVector("Debug: create B_data_size = ", B_data_size);
1034 
1035  B->CreateEndpoint(B_data_size, B_data_chunk_size, B_data_overlap_size);
1036  //PrintVector("Debug: write current_chunk_start_offset_v = ", current_chunk_start_offset_v);
1037  //PrintVector("Debug: write current_chunk_end_offset_v = ", current_chunk_end_offset_v);
1038  B->WriteEndpoint(current_chunk_start_offset_v, current_chunk_end_offset_v, data_point);
1039  free(data_point);
1040  }
1041  else
1042  {
1043  InferOutputSize(B_data_size, B_data_chunk_size, B_data_overlap_size, 0);
1044  B->CreateEndpoint(B_data_size, B_data_chunk_size, B_data_overlap_size);
1045  //B->WriteEndpoint(current_chunk_start_offset, current_chunk_end_offset, &current_result_chunk_data[0]);
1046  if (!skip_flag)
1047  {
1048  //PrintVector("current_chunk_start_offset = ", current_chunk_start_offset);
1049  //PrintVector("current_chunk_end_offset = ", current_chunk_end_offset);
1050  B->WriteArray(current_result_chunk_start_offset, current_chunk_end_offset, current_result_chunk_data);
1051  }
1052  else
1053  {
1054  //PrintVector("current_chunk_start_offset = ", current_result_chunk_start_offset);
1055  //PrintVector("current_chunk_end_offset = ", current_result_chunk_end_offset);
1056  B->WriteArray(current_result_chunk_start_offset, current_result_chunk_end_offset, current_result_chunk_data);
1057  }
1058  }
1059  }
1060 
1061  if (has_output_stencil_tag_flag)
1062  {
1063  for (std::map<std::string, std::string>::iterator it = output_stencil_metadata_map.begin(); it != output_stencil_metadata_map.end(); ++it)
1064  {
1065 
1066  B->SetTag(it->first, it->second);
1067  //std::cout << "Key: " << it->first << std::endl();
1068  //std::cout << "Value: " << it->second << std::endl();
1069  }
1070  has_output_stencil_tag_flag = false;
1071  }
1072 
1073  time_write = time_write + AU_WTIME - t_start;
1074 
1075  if (vector_type_flag == true)
1076  {
1077  previous_output_vector_shape = output_vector_shape;
1078  }
1079 
1080  t_start = AU_WTIME;
1081  load_ret = LoadNextChunk(current_result_chunk_data_size);
1082  current_result_chunk_data.resize(current_result_chunk_data_size);
1083  time_read = time_read + AU_WTIME - t_start;
1084 
1085  } // end of while:: no more chunks to process
1086 
1087  //May start a empty write for collective I/O
1088  if ((data_total_chunks % ft_size != 0) && (current_chunk_id >= data_total_chunks) && (current_chunk_id < (data_total_chunks + ft_size - (data_total_chunks % ft_size))) && B != nullptr)
1089  {
1090  //std::cout << "current_chunk_id = " << current_chunk_id << std::endl;
1091  //std::cout << "leftover_chunks = " << data_total_chunks % ft_size << std::endl;
1092  //std::cout << "data_total_chunks = " << data_total_chunks << std::endl;
1093  std::vector<unsigned long long> null_start; //Start offset on disk
1094  std::vector<unsigned long long> null_end; //End offset on disk
1095  void *data_point = nullptr;
1096  null_start.resize(data_dims, 0);
1097  null_end.resize(data_dims, 0);
1098  B->WriteEndpoint(null_start, null_end, data_point);
1099  }
1100 
1101  return;
1102  }
1103 
1104  int WriteArray(const std::vector<unsigned long long> &start_p, const std::vector<unsigned long long> &end_p, std::vector<T> &data_p)
1105  {
1106  if (!is_endpoint_created_flag)
1107  {
1108  CreateEndpoint(data_size, data_chunk_size, data_overlap_size);
1109  }
1110  //InitializeApplyInput();
1111  if (!virtual_array_flag)
1112  {
1113  return endpoint->Write(start_p, end_p, static_cast<void *>(data_p.data()));
1114  }
1115  else
1116  {
1117 
1118  int n = attribute_endpoint_vector.size();
1119  for (int i = 0; i < n; i++)
1120  {
1121  //std::cout << "write " << i << " \n" ;
1122  void *current_chunk_data_void_p = ExtractAttributeFromVirtualArrayVector(data_p, i, attribute_endpoint_vector[i]->GetDataElementType(), attribute_endpoint_vector[i]->GetDataElementTypeSize());
1123  attribute_endpoint_vector[i]->Write(start_p, end_p, current_chunk_data_void_p);
1124  free(current_chunk_data_void_p);
1125  }
1126  return 1;
1127  }
1128  }
1129 
1140  int ReadModifyWriteArray(const std::vector<unsigned long long> &start_p, const std::vector<unsigned long long> &end_p, std::vector<T> &data_p, AU_Op op)
1141  {
1142  if (!is_endpoint_created_flag)
1143  {
1144  CreateEndpoint(data_size, data_chunk_size, data_overlap_size);
1145  }
1146  //InitializeApplyInput();
1147  if (!virtual_array_flag)
1148  {
1149  std::vector<T> data_p_read;
1150  data_p_read.resize(data_p.size());
1151  endpoint->Read(start_p, end_p, static_cast<void *>(data_p.data()));
1152  switch (op)
1153  {
1154  case AU_SUM:
1155  std::transform(data_p_read.begin(), data_p_read.end(), data_p.begin(), data_p.begin(), std::plus<T>());
1156  break;
1157  default:
1158  AU_EXIT("Not supported op type in ReadModifyWriteArray now\n");
1159  break;
1160  }
1161  return endpoint->Write(start_p, end_p, static_cast<void *>(data_p.data()));
1162  }
1163  else
1164  {
1165 
1166  AU_EXIT("Not supported ReadModifyWriteArray on virtual array yet !\n");
1167  return -1;
1168  }
1169  }
1170 
1171  int WriteArray(std::vector<unsigned long long> &start_p, std::vector<unsigned long long> &end_p, std::vector<std::vector<T>> data_p)
1172  {
1173  AU_EXIT("You should not be here !");
1174  return 0;
1175  }
1176 
1177  int WriteEndpoint(std::vector<unsigned long long> &start_p, std::vector<unsigned long long> &end_p, void *data)
1178  {
1179  if (!virtual_array_flag)
1180  return endpoint->Write(start_p, end_p, data);
1181 
1182  return 0;
1183  }
1184 
1185  int ReadEndpoint(std::vector<unsigned long long> &start_p, std::vector<unsigned long long> &end_p, void *data)
1186  {
1187  return endpoint->Read(start_p, end_p, data);
1188  }
1189 
1197  void inline CalculateOutputSize(std::vector<unsigned long long> &data_size_p, std::vector<int> &data_chunk_size_p, std::vector<int> &data_overlap_size_p)
1198  {
1199  if (skip_flag)
1200  {
1201  data_size_p = skiped_dims_size;
1202  data_chunk_size_p = skiped_chunk_size;
1203  data_overlap_size_p = data_overlap_size; //Todo: need to consider data_overlap size
1204  }
1205  else
1206  {
1207  data_size_p = data_size;
1208  data_chunk_size_p = data_chunk_size;
1209  data_overlap_size_p = data_overlap_size;
1210  }
1211 
1212  //we may update the data_size_p/data_chunk_size_p/data_overlap_size_p if vector used
1213  //output_vector_shape is the parameter
1214  if (vector_type_flag)
1215  {
1216  int rank = data_size_p.size();
1217  for (int i = 0; i < output_vector_shape.size(); i++)
1218  {
1219  if (i >= rank)
1220  {
1221  data_size_p.push_back(output_vector_shape[i]);
1222  data_chunk_size_p.push_back(output_vector_shape[i]);
1223  data_overlap_size_p.push_back(0);
1224  }
1225  else
1226  {
1227  if (skip_not_aligned_w_array_flag && skip_not_aligned_w_array_index == i)
1228  {
1229  if (!is_the_last_chunk)
1230  {
1231  data_size_p[i] = (data_size_p[i] - 1) * output_vector_shape[i];
1232  data_size_p[i] = data_size_p[i] + ((data_size[i] % skip_size[i]) * output_vector_shape[i]) / data_chunk_size[i];
1233  }
1234  else
1235  {
1236  //we need to update the output_vector_shape, data_chunk_size, current_chunk_ol_size
1237  //PrintVector("data_chunk_size");
1238  int normal_chunk_output_size = data_chunk_size[i] / (current_chunk_ol_size[i] / output_vector_shape[i]);
1239  /*PrintScalar("data_chunk_size[i] =", data_chunk_size[i]);
1240  PrintScalar("current_chunk_ol_size[i] =", current_chunk_ol_size[i]);
1241  PrintScalar("output_vector_shape[i] =", output_vector_shape[i]);
1242  PrintScalar("normal_chunk_output_size =", normal_chunk_output_size);
1243  PrintScalar("skip_size[i] = ", skip_size[i]);
1244  PrintScalar("data_size[i] = ", data_size[i]);
1245  PrintScalar("data_size[i] % skip_size[i] = ", data_size[i] % skip_size[i]);*/
1246 
1247  data_size_p[i] = (data_size_p[i] - 1) * normal_chunk_output_size;
1248  data_size_p[i] = data_size_p[i] + ((data_size[i] % skip_size[i]) * normal_chunk_output_size) / data_chunk_size[i];
1249  }
1250  }
1251  else
1252  {
1253  data_size_p[i] = data_size_p[i] * output_vector_shape[i];
1254  }
1255  }
1256  }
1257  }
1258  }
1267  void inline InferOutputSize(std::vector<unsigned long long> &data_size_p, std::vector<int> &data_chunk_size_p, std::vector<int> &data_overlap_size_p, size_t output_vector_size)
1268  {
1269  if (skip_flag)
1270  {
1271  if (!vector_type_flag)
1272  {
1273  data_size_p = skiped_dims_size;
1274  data_chunk_size_p = skiped_chunk_size;
1275  data_overlap_size_p = data_overlap_size; //Todo: need to consider data_overlap size
1276  }
1277  else //skip_flag == true and vector_type_flag == true
1278  {
1279  int data_dims_t;
1280  std::vector<unsigned long long> skiped_dims_size_t;
1281  std::vector<int> skiped_chunk_size_t;
1282  std::vector<int> data_overlap_size_t;
1283 
1284  if (output_vector_flat_direction_index > (data_dims - 1))
1285  { //We save the output vector as new dimensions
1286  data_dims_t = data_dims + 1;
1287  skiped_dims_size_t.resize(data_dims_t);
1288  skiped_chunk_size_t.resize(data_dims_t);
1289  data_overlap_size_t.resize(data_dims_t);
1290  for (int k = 0; k < data_dims; k++)
1291  {
1292  skiped_dims_size_t[k] = skiped_dims_size[k];
1293  data_overlap_size_t[k] = data_overlap_size[k];
1294  skiped_chunk_size_t[k] = skiped_chunk_size[k];
1295  }
1296  skiped_dims_size_t[data_dims] = output_vector_size;
1297  data_overlap_size_t[data_dims] = 0;
1298  skiped_chunk_size_t[data_dims] = output_vector_size;
1299  }
1300  else
1301  { //We save the output vector within existing dimensions
1302  data_dims_t = data_dims;
1303  skiped_dims_size_t.resize(data_dims_t);
1304  skiped_chunk_size_t.resize(data_dims_t);
1305  data_overlap_size_t.resize(data_dims_t);
1306  for (int k = 0; k < data_dims; k++)
1307  {
1308  skiped_dims_size_t[k] = skiped_dims_size[k];
1309  if (k == output_vector_flat_direction_index)
1310  skiped_dims_size_t[k] = skiped_dims_size_t[k] * output_vector_size;
1311  data_overlap_size_t[k] = data_overlap_size[k];
1312  skiped_chunk_size_t[k] = skiped_chunk_size[k];
1313  }
1314  }
1315 
1316  data_size_p = skiped_dims_size_t;
1317  data_chunk_size_p = skiped_chunk_size_t;
1318  data_overlap_size_p = data_overlap_size_t;
1319  }
1320  }
1321  else
1322  { //skip_flag == false
1323  if (vector_type_flag == 0)
1324  {
1325  data_size_p = data_size;
1326  data_chunk_size_p = data_chunk_size;
1327  data_overlap_size_p = data_overlap_size;
1328  }
1329  else //skip_flag == false and vector_type_flag == true
1330  {
1331  int data_dims_t;
1332  std::vector<unsigned long long> dims_size_t;
1333  std::vector<int> chunk_size_t;
1334  std::vector<int> data_overlap_size_t;
1335 
1336  if (output_vector_flat_direction_index > (data_dims - 1))
1337  {
1338  data_dims_t = data_dims + 1;
1339  dims_size_t.resize(data_dims_t);
1340  chunk_size_t.resize(data_dims_t);
1341  data_overlap_size_t.resize(data_dims_t);
1342  for (int k = 0; k < data_dims; k++)
1343  {
1344  dims_size_t[k] = data_size[k];
1345  chunk_size_t[k] = data_chunk_size[k];
1346  data_overlap_size_t[k] = data_overlap_size[k];
1347  }
1348  dims_size_t[data_dims] = output_vector_size;
1349  data_overlap_size_t[data_dims] = 0;
1350  chunk_size_t[data_dims] = output_vector_size;
1351  }
1352  else
1353  {
1354  data_dims_t = data_dims;
1355  dims_size_t.resize(data_dims_t);
1356  chunk_size_t.resize(data_dims_t);
1357  data_overlap_size_t.resize(data_dims_t);
1358  for (int k = 0; k < data_dims; k++)
1359  {
1360  dims_size_t[k] = data_size[k];
1361  if (k == output_vector_flat_direction_index)
1362  dims_size_t[k] = dims_size_t[k] * output_vector_size;
1363  // dims_size_t[k] = data_dims_size[k] * output_vector_size;
1364  chunk_size_t[k] = data_chunk_size[k];
1365  data_overlap_size_t[k] = data_overlap_size[k];
1366  }
1367  }
1368 
1369  data_size_p = dims_size_t;
1370  data_chunk_size_p = chunk_size_t;
1371  data_overlap_size_p = data_overlap_size_t;
1372  }
1373  }
1374  }
1375 
1376  int inline CreateEndpoint(std::vector<unsigned long long> data_size_p, std::vector<int> data_chunk_size_p, std::vector<int> data_overlap_size_p)
1377  {
1378  if (!virtual_array_flag && endpoint->GetOpenFlag())
1379  return 0;
1380 
1381  if (is_endpoint_created_flag)
1382  return 0;
1383 
1384  //cout << "CreateEndpoint: is_endpoint_created_flag " << is_endpoint_created_flag << "\n";
1385  is_endpoint_created_flag = true;
1386 
1387  data_size = data_size_p;
1388  data_chunk_size = data_chunk_size_p;
1389  data_overlap_size = data_overlap_size_p;
1390 
1391  if (virtual_array_flag)
1392  {
1393  for (int i = 0; i < attribute_endpoint_vector.size(); i++)
1394  {
1395  if (attribute_endpoint_vector[i]->GetOpenFlag())
1396  return 0;
1397  attribute_endpoint_vector[i]->SetDimensions(data_size);
1398  attribute_endpoint_vector[i]->Create();
1399  attribute_endpoint_vector[i]->Close(); //call it to make sure it is consistency
1400  }
1401  return 0;
1402  }
1403  else
1404  {
1405  AuEndpointDataType type_p = InferDataType<T>();
1406  endpoint->SetDimensions(data_size);
1407  endpoint->SetDataElementType(type_p);
1408  return endpoint->Create();
1409  }
1410  }
1411 
1412  int ReadArray(const std::vector<unsigned long long> &start, const std::vector<unsigned long long> &end, std::vector<T> &data_vector)
1413  {
1414  //InitializeApplyInput();
1415  unsigned long long data_vector_size;
1416  COUNT_CELLS(start, end, data_vector_size);
1417 
1418  //std::vector<T> data_vector;
1419  data_vector.resize(data_vector_size);
1420  if (!virtual_array_flag)
1421  {
1422  endpoint->Read(start, end, &data_vector[0]);
1423  }
1424  else
1425  {
1426  int n = attribute_endpoint_vector.size();
1427  std::vector<AuEndpointDataTypeUnion> current_chunk_data_union_vector;
1428  for (int i = 0; i < n; i++)
1429  {
1430  int element_type_size = attribute_endpoint_vector[i]->GetDataElementTypeSize();
1431  void *current_chunk_data_temp = (void *)malloc(data_vector_size * element_type_size);
1432  if (!current_chunk_data_temp)
1433  {
1434  AU_EXIT("Not enough memory");
1435  }
1436  attribute_endpoint_vector[i]->Read(start, end, current_chunk_data_temp);
1437  current_chunk_data_union_vector = attribute_endpoint_vector[i]->Void2Union(current_chunk_data_temp, data_vector_size);
1438  InsertAttribute2VirtualArrayVector(current_chunk_data_union_vector, attribute_endpoint_vector[i]->GetDataElementType(), data_vector, i);
1439  free(current_chunk_data_temp);
1440  }
1441  }
1442  return 0;
1443  }
1444  inline std::vector<T> ReadArray(const std::vector<unsigned long long> start, const std::vector<unsigned long long> end) //used by the old code
1445  {
1446  std::vector<T> data_vector;
1447  ReadArray(start, end, data_vector);
1448  return data_vector;
1449  }
1450 
1452  {
1453  if (current_chunk_id >= data_total_chunks || current_chunk_id < 0)
1454  {
1455  return false;
1456  }
1457 
1458  return true;
1459  }
1460 
1467  {
1468  prev_chunk_id = current_chunk_id;
1469  //Next chunk id
1470  if (!reverse_apply_direction_flag)
1471  {
1472  current_chunk_id = current_chunk_id + ft_size;
1473  }
1474  else
1475  {
1476  current_chunk_id = current_chunk_id - ft_size;
1477  }
1478  }
1488  int LoadNextChunk(unsigned long long &result_vector_size)
1489  {
1490  if (!HasNextChunk())
1491  {
1492  return 0;
1493  }
1494 
1495  //We only handle last chunk when skip is not even with the array size
1496  if (current_chunk_id == (data_total_chunks - 1) && skip_not_aligned_w_array_flag)
1497  is_the_last_chunk = true;
1498 
1499  result_vector_size = 0;
1500 
1501  current_chunk_cells = 1;
1502  current_result_chunk_cells = 1;
1503  current_chunk_ol_cells = 1;
1504 
1505  //PrintVector("LoadNextChunk.data_chunked_size = ", data_chunked_size);
1506  std::vector<unsigned long long> chunk_coordinate = RowMajorOrderReverse(current_chunk_id, data_chunked_size);
1507  std::vector<unsigned long long> skiped_chunk_coordinate;
1508  if (skip_flag)
1509  skiped_chunk_coordinate = RowMajorOrderReverse(current_chunk_id, skiped_chunks);
1510 
1511  //calculate the start and end of a chunk
1512  for (int i = 0; i < data_dims; i++)
1513  {
1514  if (data_chunk_size[i] * chunk_coordinate[i] < data_size[i])
1515  {
1516  current_chunk_start_offset[i] = data_chunk_size[i] * chunk_coordinate[i];
1517  }
1518  else
1519  {
1520  current_chunk_start_offset[i] = data_size[i];
1521  }
1522 
1523  if (current_chunk_start_offset[i] + data_chunk_size[i] - 1 < data_size[i])
1524  {
1525  current_chunk_end_offset[i] = current_chunk_start_offset[i] + data_chunk_size[i] - 1;
1526  }
1527  else
1528  {
1529  current_chunk_end_offset[i] = data_size[i] - 1;
1530  }
1531 
1532  assert((current_chunk_end_offset[i] - current_chunk_start_offset[i] + 1 >= 0));
1533  current_chunk_size[i] = current_chunk_end_offset[i] - current_chunk_start_offset[i] + 1;
1534  current_chunk_cells = current_chunk_cells * current_chunk_size[i];
1535 
1536  //Deal with the result chunks size
1537  if (!skip_flag)
1538  {
1539  current_result_chunk_start_offset[i] = current_chunk_start_offset[i];
1540  current_result_chunk_end_offset[i] = current_chunk_end_offset[i];
1541  current_result_chunk_cells = current_chunk_cells;
1542  }
1543  else
1544  {
1545  if (skiped_chunk_coordinate[i] * skiped_chunk_size[i] < skiped_dims_size[i])
1546  {
1547  current_result_chunk_start_offset[i] = skiped_chunk_coordinate[i] * skiped_chunk_size[i];
1548  }
1549  else
1550  {
1551  current_result_chunk_start_offset[i] = skiped_dims_size[i];
1552  }
1553 
1554  if (current_result_chunk_start_offset[i] + skiped_chunk_size[i] - 1 < skiped_dims_size[i])
1555  {
1556  current_result_chunk_end_offset[i] = current_result_chunk_start_offset[i] + skiped_chunk_size[i] - 1;
1557  }
1558  else
1559  {
1560  current_result_chunk_end_offset[i] = skiped_dims_size[i] - 1;
1561  }
1562  assert((current_result_chunk_end_offset[i] - current_result_chunk_start_offset[i] + 1 >= 0));
1563  current_result_chunk_cells = current_result_chunk_cells * (current_result_chunk_end_offset[i] - current_result_chunk_start_offset[i] + 1);
1564  }
1565 
1566  //Deal with overlapping
1567  //Starting coordinate for the data chunk with overlapping
1568  if (current_chunk_start_offset[i] <= data_overlap_size[i])
1569  {
1570  current_chunk_ol_start_offset[i] = 0;
1571  }
1572  else
1573  {
1574  current_chunk_ol_start_offset[i] = current_chunk_start_offset[i] - data_overlap_size[i];
1575  }
1576  //Original coordinate offset for each, used to get gloabl coordinate in Apply
1577  ol_origin_offset[i] = current_chunk_start_offset[i] - current_chunk_ol_start_offset[i];
1578 
1579  //Ending oordinate for the data chunk with overlapping
1580  if (current_chunk_end_offset[i] + data_overlap_size[i] < data_size[i])
1581  {
1582  current_chunk_ol_end_offset[i] = current_chunk_end_offset[i] + data_overlap_size[i];
1583  }
1584  else
1585  {
1586  current_chunk_ol_end_offset[i] = data_size[i] - 1;
1587  }
1588  assert((current_chunk_ol_end_offset[i] - current_chunk_ol_start_offset[i] + 1 >= 0));
1589  current_chunk_ol_size[i] = current_chunk_ol_end_offset[i] - current_chunk_ol_start_offset[i] + 1;
1590  current_chunk_ol_cells = current_chunk_ol_cells * current_chunk_ol_size[i];
1591  }
1592 
1593  current_chunk_data.resize(current_chunk_ol_cells);
1594  if (save_result_flag == 1)
1595  {
1596  if (!skip_flag)
1597  {
1598  result_vector_size = current_chunk_cells;
1599  }
1600  else
1601  {
1602  result_vector_size = current_result_chunk_cells;
1603  }
1604  }
1605 
1606  if (view_flag == 1)
1607  {
1608  for (int i = 0; i < data_dims; i++)
1609  {
1610  current_chunk_ol_start_offset[i] = current_chunk_ol_start_offset[i] + view_start_offset[i];
1611  current_chunk_ol_end_offset[i] = current_chunk_ol_end_offset[i] + view_start_offset[i];
1612  }
1613  }
1614 
1615  //update current_chunk_id
1616  SchduleChunkNext();
1617 
1618  //Return 1, data read into local_chunk_data
1619  //Return 0, end of file (no data left to handle)
1620  //Return -1: error happen
1621  //Read data between local_chunk_start_offset and local_chunk_end_offset
1622  //current_chunk_data.resize(current_chunk_cells);
1623  //return data_on_disk->ReadData(current_chunk_start_offset, current_chunk_end_offset, current_chunk_data);
1624  if (!virtual_array_flag)
1625  {
1626  endpoint->Read(current_chunk_ol_start_offset, current_chunk_ol_end_offset, &current_chunk_data[0]);
1627  //Get the tag if needed
1628  if (get_stencil_tag_flag)
1629  {
1630  std::vector<std::string> stencil_tag_names;
1631  GetAllTagName(stencil_tag_names);
1632  //Here we assume all value are string
1633  std::string tag_value;
1634  for (int i = 0; i < stencil_tag_names.size(); i++)
1635  {
1636  GetTag(stencil_tag_names[i], tag_value);
1637  stencil_metadata_map[stencil_tag_names[i]] = tag_value;
1638  //std::cout << " tag name " << stencil_tag_names[i] << " , tag value = " << tag_value << "\n";
1639  }
1640  //endpoint->Control(stencil_metadata_map);
1641  }
1642  return 1;
1643  }
1644  else
1645  {
1646  int n = attribute_endpoint_vector.size();
1647  std::vector<AuEndpointDataTypeUnion> current_chunk_data_union_vector;
1648  for (int i = 0; i < n; i++)
1649  {
1650  int element_type_size = attribute_endpoint_vector[i]->GetDataElementTypeSize();
1651  void *current_chunk_data_temp = (void *)malloc(current_chunk_ol_cells * element_type_size);
1652  if (!current_chunk_data_temp)
1653  {
1654  AU_EXIT("Not enough memory");
1655  }
1656  attribute_endpoint_vector[i]->Read(current_chunk_ol_start_offset, current_chunk_ol_end_offset, current_chunk_data_temp);
1657  current_chunk_data_union_vector = attribute_endpoint_vector[i]->Void2Union(current_chunk_data_temp, current_chunk_ol_cells);
1658  InsertAttribute2VirtualArrayVector(current_chunk_data_union_vector, attribute_endpoint_vector[i]->GetDataElementType(), current_chunk_data, i);
1659  free(current_chunk_data_temp);
1660  }
1661  return 1;
1662  }
1663  }
1664 
1665  inline int EnableApplyStride(const std::vector<int> &skip_size_p)
1666  {
1667  return SetStride(skip_size_p);
1668  }
1669 
1670  inline int SetStride(const std::vector<int> &skip_size_p)
1671  {
1672  skip_size = skip_size_p;
1673  skip_flag = true;
1674  return 0;
1675  }
1676 
1678  {
1679  output_vector_flat_direction_index = flat_direction_index;
1680  }
1681 
1688  void ControlOutputVector(OutputVectorFlatDirection flat_direction, std::vector<size_t> flat_shape)
1689  {
1690  output_vector_flat_direction_index = flat_direction;
1691  output_vector_flat_shape = flat_shape;
1692  }
1693 
1694  template <typename... Is>
1695  inline T operator()(Is... indexs) const
1696  {
1697  std::vector<int> iv{{indexs...}};
1698  std::vector<unsigned long long> start;
1699  std::vector<unsigned long long> end;
1700  std::vector<T> data_v;
1701 
1702  start.resize(iv.size());
1703  end.resize(iv.size());
1704  data_v.resize(iv.size());
1705 
1706  for (int i = 0; i < iv.size(); i++)
1707  {
1708  start[i] = iv[i];
1709  end[i] = iv[i];
1710  }
1711 
1712  endpoint->Read(start, end, static_cast<void *>(data_v.data()));
1713  return data_v[0];
1714  }
1715 
1723  template <typename... Is>
1724  inline T GetValue(Is... indexs)
1725  {
1726  std::vector<int> iv{{indexs...}};
1727  std::vector<unsigned long long> start;
1728  std::vector<unsigned long long> end;
1729 
1730  start.resize(iv.size());
1731  end.resize(iv.size());
1732 
1733  for (int i = 0; i < iv.size(); i++)
1734  {
1735  start[i] = iv[i];
1736  end[i] = iv[i];
1737  }
1738 
1739  if (virtual_array_flag == 0)
1740  {
1741  std::vector<T> data_v;
1742  data_v.resize(1);
1743  endpoint->Read(start, end, static_cast<void *>(data_v.data()));
1744  return data_v[0];
1745  }
1746  else
1747  {
1748  std::vector<T> data_v;
1749  ReadArray(start, end, data_v);
1750  return data_v[0];
1751  }
1752  }
1753 
1754  template <typename... Is>
1755  inline void SetValue(T data_p, Is... indexs)
1756  {
1757  std::vector<int> iv{{indexs...}};
1758  std::vector<unsigned long long> start;
1759  std::vector<unsigned long long> end;
1760  std::vector<T> data_v;
1761 
1762  start.resize(iv.size());
1763  end.resize(iv.size());
1764  data_v.resize(1);
1765 
1766  data_v[0] = data_p;
1767  for (int i = 0; i < iv.size(); i++)
1768  {
1769  start[i] = iv[i];
1770  end[i] = iv[i];
1771  }
1772  if (!is_endpoint_created_flag)
1773  {
1774  CreateEndpoint(data_size, data_chunk_size, data_overlap_size);
1775  }
1776 
1777  endpoint->Write(start, end, static_cast<void *>(data_v.data()));
1778  }
1779 
1780  template <class AttributeType>
1781  void PushBackAttribute(std::string data_endpoint)
1782  {
1783  if (attribute_endpoint_vector.size() == 0)
1784  virtual_array_flag = true;
1785  Endpoint *attribute_endpoint = EndpointFactory::NewEndpoint(data_endpoint);
1786  AuEndpointDataType data_element_type = InferDataType<AttributeType>();
1787  attribute_endpoint->SetDataElementType(data_element_type);
1788  if (attribute_endpoint->GetEndpointType() == EP_MEMORY)
1789  endpoint_memory_flag = true;
1790 
1791  //Fixme: here it assign first attribute's endpoint to the object's endpoint
1792  if (attribute_endpoint_vector.size() == 0)
1793  {
1794  endpoint = attribute_endpoint;
1795  }
1796  attribute_endpoint_vector.push_back(attribute_endpoint);
1797  }
1798 
1799  template <class AttributeType>
1800  int AppendAttribute(const std::string &data_endpoint)
1801  {
1802  if (attribute_endpoint_vector.size() == 0)
1803  virtual_array_flag = true;
1804  Endpoint *attribute_endpoint = EndpointFactory::NewEndpoint(data_endpoint);
1805  AuEndpointDataType data_element_type = InferDataType<AttributeType>();
1806  attribute_endpoint->SetDataElementType(data_element_type);
1807  if (attribute_endpoint->GetEndpointType() == EP_MEMORY)
1808  endpoint_memory_flag = true;
1809  attribute_endpoint_vector.push_back(attribute_endpoint);
1810  attribute_array_data_endpoint_info.push_back(data_endpoint);
1811  //add to clean
1812  //endpoint_clean_vector[attribute_endpoint] = true;
1813  endpoint_to_clean_vector.push_back(attribute_endpoint);
1814 
1815  return 0;
1816  }
1817 
1818  template <class AttributeType>
1819  int InsertAttribute(const std::string &data_endpoint, const int index)
1820  {
1821  if (attribute_endpoint_vector.size() == 0)
1822  virtual_array_flag = true;
1823  Endpoint *attribute_endpoint = EndpointFactory::NewEndpoint(data_endpoint);
1824  AuEndpointDataType data_element_type = InferDataType<AttributeType>();
1825  attribute_endpoint->SetDataElementType(data_element_type);
1826  attribute_endpoint_vector.insert(attribute_endpoint_vector.begin() + index, attribute_endpoint);
1827  attribute_array_data_endpoint_info.insert(attribute_array_data_endpoint_info.begin() + index, data_endpoint);
1828  if (attribute_endpoint->GetEndpointType() == EP_MEMORY)
1829  endpoint_memory_flag = true;
1830  //add to clean
1831  //endpoint_clean_vector[attribute_endpoint] = true;
1832  endpoint_to_clean_vector.push_back(attribute_endpoint);
1833  return 0;
1834  }
1835 
1836  //index is zero based
1837  int EraseAttribute(const int &index)
1838  {
1839  if (attribute_endpoint_vector[index] != NULL)
1840  {
1841  delete attribute_endpoint_vector[index];
1842  }
1843  attribute_endpoint_vector.erase(attribute_endpoint_vector.begin() + index);
1844  attribute_array_data_endpoint_info.erase(attribute_array_data_endpoint_info.begin() + index);
1845  return 0;
1846  }
1847 
1848  int GetAttribute(const int &index, std::string &endpoint_id)
1849  {
1850  if (index < attribute_array_data_endpoint_info.size())
1851  {
1852  endpoint_id = attribute_array_data_endpoint_info[index];
1853  return 0;
1854  }
1855  return -1;
1856  }
1857 
1858  std::vector<Endpoint *> GetAttributeEndpoint()
1859  {
1860  return attribute_endpoint_vector;
1861  }
1862 
1864  {
1865  return virtual_array_flag;
1866  }
1867 
1868  void SetVirtualArrayFlag(bool flag_p)
1869  {
1870  virtual_array_flag = true;
1871  }
1872 
1873  void SetDirOutputRegexReplace(std::regex &regex_p, std::string &replace_str_p)
1874  {
1875  dir_output_regex = regex_p;
1876  dir_output_replace_str = replace_str_p;
1877  }
1878 
1879  void SetDirInputRegexSearch(std::regex &regex_p)
1880  {
1881  dir_input_regex = regex_p;
1882  }
1883 
1885  {
1886  if (!virtual_array_flag)
1887  {
1888  return endpoint->GetEndpointType();
1889  }
1890  else
1891  {
1892  return attribute_endpoint_vector[0]->GetEndpointType();
1893  }
1894  }
1895 
1896  std::vector<std::string> GetDirFile()
1897  {
1898  return endpoint->GetDirFileVector();
1899  }
1900 
1901  void SetDirFile(std::vector<std::string> &file_list)
1902  {
1903  endpoint->SetDirFileVector(file_list);
1904  }
1905 
1906  std::vector<int> GetDirChunkSize()
1907  {
1908  return endpoint->GetDirChunkSize();
1909  }
1910 
1911  inline void SetDirChunkSize(std::vector<int> &dir_chunk_size_p)
1912  {
1913  endpoint->SetDirChunkSize(dir_chunk_size_p);
1914  }
1915 
1916  inline int SetChunkSize(std::vector<int> data_chunk_size_p)
1917  {
1918  data_chunk_size = data_chunk_size_p;
1919  return 0;
1920  }
1921 
1922  inline int GetChunkSize(std::vector<int> &data_chunk_size_p)
1923  {
1924  data_chunk_size_p = data_chunk_size;
1925  return 0;
1926  }
1927  inline std::vector<int> GetChunkSize()
1928  {
1929  std::vector<int> data_chunk_size_p;
1930  GetChunkSize(data_chunk_size_p);
1931  return data_chunk_size_p;
1932  }
1933 
1934  inline int SetChunkSizeByMem(size_t max_mem_size)
1935  {
1936  set_chunk_size_by_mem_flag = true;
1937  set_chunk_size_by_mem_max_mem_size = max_mem_size;
1938  return 0;
1939  }
1940 
1941  inline int SetChunkSizeByDim(int dim_rank)
1942  {
1943  chunk_size_by_user_by_dimension_flag = true;
1944  data_auto_chunk_dim_index = dim_rank;
1945  return 0;
1946  }
1947 
1948  inline int GetArraySize(std::vector<unsigned long long> &size_p)
1949  {
1950  if (endpoint != NULL)
1951  {
1952  endpoint->ExtractMeta();
1953  data_size = endpoint->GetDimensions();
1954  size_p = data_size;
1955  return 0;
1956  }
1957  return -1;
1958  }
1959 
1960  inline int SetArraySize(const std::vector<unsigned long long> &size_p)
1961  {
1962  data_size = size_p;
1963  return 0;
1964  }
1965 
1966  inline int GetArrayRank(int &rank)
1967  {
1968  if (endpoint != NULL)
1969  {
1970  endpoint->ExtractMeta();
1971  data_size = endpoint->GetDimensions();
1972  rank = data_size.size();
1973  return 0;
1974  }
1975  return -1;
1976  }
1977 
1978  /*
1979  void SetSize(std::vector<unsigned long long> size_p)
1980  {
1981  data_size = size_p;
1982  }
1983  std::vector<unsigned long long> GetSize()
1984  {
1985  if (endpoint != NULL)
1986  {
1987  endpoint->ExtractMeta();
1988  data_size = endpoint->GetDimensions();
1989  data_dims = data_size.size();
1990  return data_size;
1991  }
1992  }
1993  */
1994 
2001  int Backup(std::string data_endpoint_p)
2002  {
2003  //std::string target_array_data_endpoint_info = data_endpoint_p;
2004  //Endpoint *target_endpoint = EndpointFactory::NewEndpoint(data_endpoint_p);
2005 
2006  AuEndpointType target_endpoint_type;
2007  std::string endpoint_info;
2008  ExtractEndpointTypeInfo(data_endpoint_p, target_endpoint_type, endpoint_info);
2009 
2010  int ret;
2011  if (endpoint_memory_flag == true && target_endpoint_type == EP_HDF5)
2012  {
2013  std::vector<std::string> arg_v;
2014  arg_v.push_back(endpoint_info);
2015  ret = endpoint->Control(0, arg_v);
2016  }
2017  else
2018  {
2019  AU_EXIT("Nonvolatile: only support MEMORY to HDF5 now!");
2020  }
2021 
2022  return ret;
2023  }
2024  inline int Nonvolatile(std::string data_endpoint_p) // used by the old code
2025  {
2026  return Backup(data_endpoint_p);
2027  }
2028 
2035  int Restore(std::string data_endpoint_p)
2036  {
2037  std::string target_array_data_endpoint_info = data_endpoint_p;
2038  Endpoint *target_endpoint = EndpointFactory::NewEndpoint(data_endpoint_p);
2039  int ret;
2040  if (endpoint_memory_flag == true && target_endpoint->GetEndpointType() == EP_HDF5)
2041  {
2042  std::vector<std::string> arg_v;
2043  arg_v.push_back(target_endpoint->GetEndpointInfo());
2044  ret = endpoint->Control(1, arg_v);
2045  }
2046  else
2047  {
2048  AU_EXIT("Volatile: only support HDF5 to MEMORY now!");
2049  }
2050 
2051  return ret;
2052  }
2053  inline int Volatile(std::string data_endpoint_p) // used by the old code
2054  {
2055  Restore(data_endpoint_p);
2056  }
2057 
2064  int Clone(T intial_value)
2065  {
2066  std::vector<std::string> intial_value_str;
2067  intial_value_str.push_back(std::to_string(intial_value));
2068 
2069  endpoint->Control(DASH_ENABLE_LOCAL_MIRROR_CODE, intial_value_str);
2070  return 0;
2071  }
2072 
2078  int Clone()
2079  {
2080  //std::string intial_value_str = ""; //Empty string
2081  std::vector<std::string> op_str;
2082 
2083  endpoint->Control(DASH_ENABLE_LOCAL_MIRROR_CODE, op_str);
2084  return 0;
2085  }
2086 
2087  int Merge(int Op)
2088  {
2089  std::vector<std::string> op_str;
2090  op_str.push_back(std::to_string(Op));
2091  endpoint->Control(DASH_MERGE_MIRRORS_CODE, op_str);
2092  return 0;
2093  }
2094 
2101  int Fill(T fill_value)
2102  {
2103  if (!ft_rank)
2104  {
2105  unsigned long long total_size = 1;
2106  std::vector<unsigned long long> start_p(data_size.size());
2107  std::vector<unsigned long long> end_p(data_size.size());
2108 
2109  for (int i = 0; i < data_size.size(); i++)
2110  {
2111  start_p[i] = 0;
2112  end_p[i] = data_size[i] - 1;
2113  total_size = total_size * data_size[i];
2114  }
2115  std::vector<T> default_value_v(total_size, fill_value);
2116  endpoint->Write(start_p, end_p, static_cast<void *>(default_value_v.data()));
2117  }
2118 
2119  return 0;
2120  }
2121 
2122  inline int SetEndpoint(const string &endpoint_id)
2123  {
2124  array_data_endpoint_info = endpoint_id;
2125  endpoint = EndpointFactory::NewEndpoint(endpoint_id);
2126  AuEndpointDataType data_element_type = InferDataType<T>();
2127  endpoint->SetDataElementType(data_element_type);
2128 
2129  if (endpoint->GetEndpointType() == EP_MEMORY)
2130  {
2131  endpoint_memory_flag = true;
2132  }
2133  //endpoint_clean_vector[endpoint] = true;
2134  endpoint_to_clean_vector.push_back(endpoint);
2135 
2136  return 0;
2137  }
2138  inline int GetEndpoint(string &endpoint_id)
2139  {
2140  endpoint_id = array_data_endpoint_info;
2141  return 0;
2142  }
2143 
2150  int ControlEndpoint(int cmd_p, std::vector<std::string> &arg_v_p)
2151  {
2152  return endpoint->Control(cmd_p, arg_v_p);
2153  }
2154 
2155  int ControlEndpoint(int cmd_p)
2156  {
2157  std::vector<std::string> arg_v_p;
2158  return endpoint->Control(cmd_p, arg_v_p);
2159  }
2160 
2161  //For old code
2162  inline int EndpointControl(int cmd_p, std::vector<std::string> &arg_v_p)
2163  {
2164  return ControlEndpoint(cmd_p, arg_v_p);
2165  }
2166 
2167  void inline ReportCost()
2168  {
2169  std::vector<double> mpi_stats_read, mpi_stats_udf, mpi_stats_write;
2170  MPIReduceStats(time_read, mpi_stats_read);
2171  MPIReduceStats(time_udf, mpi_stats_udf);
2172  MPIReduceStats(time_write, mpi_stats_write);
2173 
2174  if (ft_rank == 0)
2175  {
2176  std::cout << "Timing Results of All " << std::endl;
2177  std::cout << "Read time (s) : max = " << mpi_stats_read[0] << ", min = " << mpi_stats_read[1] << ", ave = " << mpi_stats_read[2] / ft_size << std::endl;
2178  std::cout << "UDF time (s) : max = " << mpi_stats_udf[0] << ", min = " << mpi_stats_udf[1] << ", ave = " << mpi_stats_udf[2] / ft_size << std::endl;
2179  std::cout << "Write time (s) : max = " << mpi_stats_write[0] << ", min = " << mpi_stats_write[1] << ", ave = " << mpi_stats_write[2] / ft_size << std::endl;
2180  fflush(stdout);
2181  }
2182  }
2183  //Old-code
2184  inline void ReportTime()
2185  {
2186  ReportCost();
2187  }
2188 
2189  inline int GetReadCost(vector<double> &cost_stats)
2190  {
2191  MPIReduceStats(time_read, cost_stats);
2192  cost_stats[2] = cost_stats[2] / ft_size;
2193  return 0;
2194  }
2195 
2196  inline int GetWriteCost(vector<double> &cost_stats)
2197  {
2198  MPIReduceStats(time_write, cost_stats);
2199  cost_stats[2] = cost_stats[2] / ft_size;
2200  return 0;
2201  }
2202  inline int GetComputingCost(vector<double> &cost_stats)
2203  {
2204  MPIReduceStats(time_udf, cost_stats);
2205  cost_stats[2] = cost_stats[2] / ft_size;
2206  return 0;
2207  }
2208 
2217  template <class PType>
2218  int SetTag(const std::string &name, const PType value)
2219  {
2220  AuEndpointDataType data_element_type = InferDataType<PType>();
2221  //std::cout << AU_DOUBLE << ", " << data_element_type << "\n";
2222  return endpoint->WriteAttribute(name, &value, data_element_type, 1);
2223  }
2224 
2225  int SetTag(const std::string &name, const std::string value)
2226  {
2227  return endpoint->WriteAttribute(name, &value[0], AU_STRING, value.length());
2228  }
2229 
2230  template <class PType>
2231  int SetTag(const std::string &name, const std::vector<PType> value)
2232  {
2233  AuEndpointDataType data_element_type = InferDataType<PType>();
2234  return endpoint->WriteAttribute(name, &value[0], data_element_type, value.size());
2235  }
2244  template <class PType>
2245  int GetTag(const std::string &name, PType &value)
2246  {
2247  AuEndpointDataType data_element_type = InferDataType<PType>();
2248  return endpoint->ReadAttribute(name, &value, data_element_type);
2249  }
2250 
2251  int GetTag(const std::string &name, std::string &value)
2252  {
2253  int str_len = endpoint->GetAttributeSize(name, AU_STRING);
2254  if (str_len < 0)
2255  {
2256  return -1;
2257  }
2258  value.resize(str_len);
2259  //std::cout << "GetTag : name = " << name << ", str_len = " << str_len << "\n";
2260  return endpoint->ReadAttribute(name, &value[0], AU_STRING, value.length());
2261  }
2262  template <class PType>
2263  int GetTag(const std::string &name, std::vector<PType> &value)
2264  {
2265  AuEndpointDataType data_element_type = InferDataType<PType>();
2266  int vec_len = endpoint->GetAttributeSize(name, data_element_type);
2267  value.resize(vec_len);
2268  return endpoint->ReadAttribute(name, &value[0], data_element_type, value.size());
2269  }
2270 
2271  int GetAllTagName(std::vector<string> &tag_name)
2272  {
2273  return endpoint->Control(OP_LIST_TAG, tag_name);
2274  }
2275 
2276  //
2277  //Below code are not used and just kept in case
2279 
2284  {
2285  if (endpoint->GetEndpointType() == EP_HDF5)
2286  {
2287  endpoint->DisableCollectiveIO();
2288  }
2289  }
2290 
2292  {
2293  if (endpoint->GetEndpointType() == EP_HDF5)
2294  {
2295  endpoint->EnableCollectiveIO();
2296  }
2297  }
2298 
2299  inline int CreateVisFile(FTVisType vis_type)
2300  {
2301  if (endpoint->GetEndpointType() == EP_HDF5 && vis_type == FT_VIS_XDMF)
2302  {
2303  std::vector<std::string> arg_v_p;
2304 
2305  return endpoint->Control(OP_CREATE_VIS_SCRIPT, arg_v_p);
2306  }
2307  else
2308  {
2309  AU_EXIT("FT only supports Create XDMF on HDF5 now !\n");
2310  }
2311  }
2312 
2313  inline int CreateVisFile()
2314  {
2315  // && vis_type == FT_VIS_XDMF
2316  if (endpoint->GetEndpointType() == EP_HDF5)
2317  {
2318  std::vector<std::string> arg_v_p;
2319 
2320  return endpoint->Control(OP_CREATE_VIS_SCRIPT, arg_v_p);
2321  }
2322  else
2323  {
2324  AU_EXIT("FT only supports Create XDMF on HDF5 now !\n");
2325  }
2326  }
2327 
2328  inline int UpdateOverlap()
2329  {
2330  }
2331 
2332  inline int SetDirectOutput()
2333  {
2334  set_direct_output_flag = true;
2335  }
2336 
2337  inline int GetStencilTag()
2338  {
2339  get_stencil_tag_flag = true;
2340  return 0;
2341  }
2342  }; // class of array
2343 } // namespace FT
2344 
2345 namespace AU = FT;
2346 #endif
static Endpoint * NewEndpoint(std::string endpoint)
create a normal endpoint
Definition: ft_endpoint_factory.h:98
Define the class for the Endpoint used by ArrayUDF to store the data. It contains basic infomation fo...
Definition: ft_endpoint.h:106
virtual int ReadAttribute(const std::string &name, void *data, FTDataType data_type_p, const size_t &data_length_p=0)
Get the Attribute object Do not need to be pure virtual method.
Definition: ft_endpoint.cpp:474
bool GetOpenFlag()
Definition: ft_endpoint.cpp:151
virtual int Read(std::vector< unsigned long long > start, std::vector< unsigned long long > end, void *data)=0
read the data from end-point
virtual int ExtractMeta()=0
extracts metadata, possbile endpoint_ranks/endpoint_dim_size/other ep_type dependents ones
virtual int Write(std::vector< unsigned long long > start, std::vector< unsigned long long > end, void *data)=0
write the data to the end-point
std::string GetEndpointInfo()
Get the endpoint_info string.
Definition: ft_endpoint.cpp:345
virtual void EnableCollectiveIO()
Definition: ft_endpoint.cpp:427
virtual std::vector< int > GetDirChunkSize()
Get the Dir Chunk Size object.
Definition: ft_endpoint.cpp:387
void SetDataElementType(AuEndpointDataType data_element_type_p)
set the type of data element
Definition: ft_endpoint.cpp:104
void SetDimensions(std::vector< unsigned long long > endpoint_dim_size_p)
Set the Dimensions.
Definition: ft_endpoint.cpp:97
virtual std::vector< std::string > GetDirFileVector()
Get the Dir File Vector object.
Definition: ft_endpoint.cpp:370
virtual void SetDirChunkSize(std::vector< int > &dir_chunk_size_p)
Set the Dir Chunk Size object.
Definition: ft_endpoint.cpp:397
virtual int Control(int opt_code, std::vector< std::string > &parameter_v)
call a special operator on endpoint such as, enable collective I/O for HDF5 dump file from MEMORY to ...
Definition: ft_endpoint.cpp:421
virtual void SetDirFileVector(std::vector< std::string > &file_list)
Set the Dir File Vector object.
Definition: ft_endpoint.cpp:377
virtual int Create()=0
create the endpoint
virtual int GetAttributeSize(const std::string &name, FTDataType data_type_p)
Definition: ft_endpoint.cpp:480
virtual int WriteAttribute(const std::string &name, const void *data, FTDataType data_type_p, const size_t &data_length_p=0)
Set the Attribute object Do not need to be pure virtual method.
Definition: ft_endpoint.cpp:461
std::vector< unsigned long long > GetDimensions()
Get the Dimensions of the data.
Definition: ft_endpoint.cpp:87
virtual int PrintInfo()=0
print information about the endpoint
virtual void DisableCollectiveIO()
Definition: ft_endpoint.cpp:431
AuEndpointType GetEndpointType()
Get the Endpoint Type object.
Definition: ft_endpoint.cpp:365
the object to the ArrayBase
Definition: ft_array.h:146
virtual int EnableApplyStride(const std::vector< int > &skip_size_p)=0
virtual int SetOverlapSize(const vector< int > os_p)=0
virtual int SetChunkSize(std::vector< int > data_chunk_size_p)=0
virtual int GetArraySize(std::vector< unsigned long long > &size_p)=0
virtual int GetTag(const std::string &name, std::string &value)=0
virtual void SetVectorDirection(OutputVectorFlatDirection flat_direction_index)=0
virtual int ControlEndpoint(int cmd_p, std::vector< std::string > &arg_v_p)=0
virtual int ControlEndpoint(int cmd_p)=0
virtual int GetStencilTag()=0
virtual void ReportCost()=0
virtual ~ArrayBase()=default
Definition: ft_array.h:163
int GetAllTagName(std::vector< string > &tag_name)
Definition: ft_array.h:2271
int SyncOverlap()
Definition: ft_array.h:576
int EndpointControl(int cmd_p, std::vector< std::string > &arg_v_p)
Definition: ft_array.h:2162
int GetChunkSize(std::vector< int > &data_chunk_size_p)
Definition: ft_array.h:1922
T operator()(Is... indexs) const
Definition: ft_array.h:1695
void Transform(Stencil< UDFOutputType >(*UDF)(const Stencil< T > &), Array< BType > &B)
Definition: ft_array.h:771
int ControlEndpoint(int cmd_p)
Definition: ft_array.h:2155
int WriteArray(const std::vector< unsigned long long > &start_p, const std::vector< unsigned long long > &end_p, std::vector< T > &data_p)
Definition: ft_array.h:1104
int ControlEndpoint(int cmd_p, std::vector< std::string > &arg_v_p)
pass command cmd to Endpoint of Array
Definition: ft_array.h:2150
int SetDirectOutput()
Definition: ft_array.h:2332
int CreateVisFile(FTVisType vis_type)
Definition: ft_array.h:2299
int SetChunkSize(std::vector< int > data_chunk_size_p)
Definition: ft_array.h:1916
Array(std::vector< T > &data_vector_endpoint, std::vector< int > cs, std::vector< int > os)
Construct a new Array object.
Definition: ft_array.h:442
int SetOverlapPadding(const T &padding_value_p)
Definition: ft_array.h:569
std::vector< std::string > GetDirFile()
Definition: ft_array.h:1896
void ReportCost()
Definition: ft_array.h:2167
int EnableApplyStride(const std::vector< int > &skip_size_p)
Definition: ft_array.h:1665
int AppendAttribute(const std::string &data_endpoint)
Definition: ft_array.h:1800
int SetTag(const std::string &name, const std::vector< PType > value)
Definition: ft_array.h:2231
int SetChunkSizeByDim(int dim_rank)
Definition: ft_array.h:1941
void SchduleChunkNext()
update current_chunk_id
Definition: ft_array.h:1466
int WriteEndpoint(std::vector< unsigned long long > &start_p, std::vector< unsigned long long > &end_p, void *data)
Definition: ft_array.h:1177
void SetVirtualArrayFlag(bool flag_p)
Definition: ft_array.h:1868
void ControlOutputVector(OutputVectorFlatDirection flat_direction, std::vector< size_t > flat_shape)
A geneic verion of function to control how to deal with output vector during the run of Apply on Arra...
Definition: ft_array.h:1688
int UpdateOverlap()
Definition: ft_array.h:2328
void DisableCollectiveIO()
merge below to EndpointControl
Definition: ft_array.h:2283
void SetDirFile(std::vector< std::string > &file_list)
Definition: ft_array.h:1901
int Clone(T intial_value)
create a local mirror (clone) of array with the inital value
Definition: ft_array.h:2064
int Volatile(std::string data_endpoint_p)
Definition: ft_array.h:2053
std::vector< int > GetChunkSize()
Definition: ft_array.h:1927
int EraseAttribute(const int &index)
Definition: ft_array.h:1837
int GetStencilTag()
Definition: ft_array.h:2337
std::vector< Endpoint * > GetAttributeEndpoint()
Definition: ft_array.h:1858
void InitializeApplyInput(Stencil< UDFOutputType >(*UDF)(const Stencil< T > &))
Definition: ft_array.h:620
int SetArraySize(const std::vector< unsigned long long > &size_p)
Definition: ft_array.h:1960
Array(std::string data_endpoint, std::vector< int > cs)
Construct a new Array object for read, as Input of Apply.
Definition: ft_array.h:313
AuEndpointType GetEndpointType()
Definition: ft_array.h:1884
void UpdateChunkSize()
Update the chunk size, given chunk_size_by_user_flag/chunk_size_by_user_by_dimension_flag.
Definition: ft_array.h:466
~Array()
Construct a new Array object from in-memory vector The data are assumed to be 1D too here.
Definition: ft_array.h:451
void SetVectorDirection(OutputVectorFlatDirection flat_direction_index)
Definition: ft_array.h:1677
void SetDirChunkSize(std::vector< int > &dir_chunk_size_p)
Definition: ft_array.h:1911
int GetReadCost(vector< double > &cost_stats)
Definition: ft_array.h:2189
Array(std::string data_endpoint, int auto_chunk_dim_index)
Construct a new Array object for read, as Input of Apply.
Definition: ft_array.h:366
int ReadModifyWriteArray(const std::vector< unsigned long long > &start_p, const std::vector< unsigned long long > &end_p, std::vector< T > &data_p, AU_Op op)
Test a new API to read modfy and write a array. It is useful for cases that you have a incremently up...
Definition: ft_array.h:1140
int SetStride(const std::vector< int > &skip_size_p)
Definition: ft_array.h:1670
void InferOutputSize(std::vector< unsigned long long > &data_size_p, std::vector< int > &data_chunk_size_p, std::vector< int > &data_overlap_size_p, size_t output_vector_size)
infer the size for output array
Definition: ft_array.h:1267
int SetTag(const std::string &name, const std::string value)
Definition: ft_array.h:2225
int CreateEndpoint(std::vector< unsigned long long > data_size_p, std::vector< int > data_chunk_size_p, std::vector< int > data_overlap_size_p)
Definition: ft_array.h:1376
int SetOverlapSize(const vector< int > os_p)
Definition: ft_array.h:554
std::vector< int > GetDirChunkSize()
Definition: ft_array.h:1906
int CreateVisFile()
Definition: ft_array.h:2313
void SetDirOutputRegexReplace(std::regex &regex_p, std::string &replace_str_p)
Definition: ft_array.h:1873
void CalculateOutputSize(std::vector< unsigned long long > &data_size_p, std::vector< int > &data_chunk_size_p, std::vector< int > &data_overlap_size_p)
Calculate the Size of Output array (B)
Definition: ft_array.h:1197
int GetArrayRank(int &rank)
Definition: ft_array.h:1966
Array(std::vector< int > cs)
Definition: ft_array.h:420
Array(std::vector< T > &data_vector_endpoint)
Construct a new Array object from in-memory vector The data are assumed to be 1D too here.
Definition: ft_array.h:431
int GetWriteCost(vector< double > &cost_stats)
Definition: ft_array.h:2196
int WriteArray(std::vector< unsigned long long > &start_p, std::vector< unsigned long long > &end_p, std::vector< std::vector< T >> data_p)
Definition: ft_array.h:1171
int GetOverlapSize(vector< int > &os_p)
Definition: ft_array.h:564
void PushBackAttribute(std::string data_endpoint)
Definition: ft_array.h:1781
Array(std::string data_endpoint)
Construct a new Array object for either Input or Output For Input, data_endpoint is opened before App...
Definition: ft_array.h:293
int InsertAttribute(const std::string &data_endpoint, const int index)
Definition: ft_array.h:1819
void SetDirInputRegexSearch(std::regex &regex_p)
Definition: ft_array.h:1879
Array(std::string data_endpoint, std::vector< unsigned long long > size_p)
Construct a new Array object for read, as Input of Apply.
Definition: ft_array.h:389
int Nonvolatile(std::string data_endpoint_p)
Definition: ft_array.h:2024
void EnableCollectiveIO()
Definition: ft_array.h:2291
int Merge(int Op)
Definition: ft_array.h:2087
int Fill(T fill_value)
Fill the array with value (only on rank 0)
Definition: ft_array.h:2101
void Apply(Stencil< UDFOutputType >(*UDF)(const Stencil< T > &), Array< BType > *B=nullptr)
Run a UDF on the data pointed by the array.
Definition: ft_array.h:765
int Restore(std::string data_endpoint_p)
load HDF5 array to IN_MEMORY array
Definition: ft_array.h:2035
Array()
Construct a new Array object for Write The data can be cached or dumped later.
Definition: ft_array.h:279
void PrintEndpointInfo()
print endpoint info of this array
Definition: ft_array.h:743
int GetEndpoint(string &endpoint_id)
Definition: ft_array.h:2138
int SetEndpoint(const string &endpoint_id)
Definition: ft_array.h:2122
int Clone()
create a local miroor (clone of array) without intial value so, it needs to copy the whole array
Definition: ft_array.h:2078
int GetTag(const std::string &name, PType &value)
Get the Attribute object.
Definition: ft_array.h:2245
void SetValue(T data_p, Is... indexs)
Definition: ft_array.h:1755
bool HasNextChunk()
Definition: ft_array.h:1451
int GetTag(const std::string &name, std::string &value)
Definition: ft_array.h:2251
int SetTag(const std::string &name, const PType value)
Set the Attribute object.
Definition: ft_array.h:2218
int ReadEndpoint(std::vector< unsigned long long > &start_p, std::vector< unsigned long long > &end_p, void *data)
Definition: ft_array.h:1185
void ReportTime()
Definition: ft_array.h:2184
int ReadArray(const std::vector< unsigned long long > &start, const std::vector< unsigned long long > &end, std::vector< T > &data_vector)
Definition: ft_array.h:1412
std::vector< T > ReadArray(const std::vector< unsigned long long > start, const std::vector< unsigned long long > end)
Definition: ft_array.h:1444
int GetArraySize(std::vector< unsigned long long > &size_p)
Definition: ft_array.h:1948
void Transform(Stencil< UDFOutputType >(*UDF)(const Stencil< T > &), Array< BType > *B=nullptr)
Run a UDF on the data pointed by the array.
Definition: ft_array.h:792
int GetComputingCost(vector< double > &cost_stats)
Definition: ft_array.h:2202
int GetTag(const std::string &name, std::vector< PType > &value)
Definition: ft_array.h:2263
int SetOverlapSizeByDetection()
Definition: ft_array.h:559
int GetAttribute(const int &index, std::string &endpoint_id)
Definition: ft_array.h:1848
T GetValue(Is... indexs)
Get the Value at indexs.
Definition: ft_array.h:1724
int Backup(std::string data_endpoint_p)
write data to another endpoint type, e.g., HDF5 in disk
Definition: ft_array.h:2001
int UpdateOverlapSize(Stencil< UDFOutputType >(*UDF)(const Stencil< T > &))
Definition: ft_array.h:592
bool GetVirtualArrayFlag()
Definition: ft_array.h:1863
int SetChunkSizeByMem(size_t max_mem_size)
Definition: ft_array.h:1934
Array(std::string data_endpoint, std::vector< int > cs, std::vector< int > os)
Construct a new Array object for read, as Input of Apply.
Definition: ft_array.h:341
Array(std::vector< int > cs, std::vector< int > os)
Construct a new Array object with only chunk size and overlap size Mostly, this is used for virtual a...
Definition: ft_array.h:414
int LoadNextChunk(unsigned long long &result_vector_size)
Load the next chunk.
Definition: ft_array.h:1488
Definition: ft_stencil.h:100
void SetLocation(unsigned long long my_offset, std::vector< unsigned long long > &my_coordinate, std::vector< unsigned long long > &my_location_no_ol_p, std::vector< unsigned long long > &chunk_dim_size_no_ol_p, std::vector< long long > ol_origin_offset_p, std::vector< unsigned long long > current_chunk_ol_size)
Definition: ft_stencil.h:946
int SetTagMap(std::map< std::string, std::string > &stencil_tag_map_p)
Definition: ft_stencil.h:1231
void SetChunkID(unsigned long long chunk_id_p)
Definition: ft_stencil.h:1226
void SetPadding(T padding_value_p)
Set the Padding object.
Definition: ft_stencil.h:1139
int GetShape(std::vector< size_t > &shape_p)
Get the Output Vector Shape object.
Definition: ft_stencil.h:1172
bool HasTagMap() const
Definition: ft_stencil.h:1245
T get_value()
Get the value object.
Definition: ft_stencil.h:864
int GetTagMap(std::map< std::string, std::string > &stencil_tag_map_p) const
Definition: ft_stencil.h:1239
int GetTrailRunResult(std::vector< int > &overlap_size_p)
Definition: ft_stencil.h:1051
int ft_rank
Definition: ft.cpp:86
std::vector< Endpoint * > endpoint_to_clean_vector
Definition: ft.cpp:90
int ft_size
Definition: ft.cpp:85
#define OP_CREATE_VIS_SCRIPT
Definition: ft_endpoint.h:96
#define OP_LIST_TAG
Definition: ft_endpoint.h:97
#define MEMORY_SYNC_OVERLAP
Definition: ft_endpoint_memory.h:104
#define DASH_ENABLE_LOCAL_MIRROR_CODE
Definition: ft_endpoint_memory.h:97
#define DASH_MERGE_MIRRORS_CODE
Definition: ft_endpoint_memory.h:98
double t_start
Definition: ft_example_stack.cpp:116
#define AU_SUM
Definition: ft_merge.h:92
int AU_Op
Definition: ft_merge.h:88
#define AU_WTIME_TYPE
Definition: ft_mpi.h:92
void MPIReduceStats(const T local_value, std::vector< T > &stats_vector)
get max/min/sum of local_value
Definition: ft_mpi.h:247
#define AU_WTIME
Definition: ft_mpi.h:93
void * InsertOutputVV2WriteV(std::vector< std::vector< T >> &v, std::vector< size_t > &v_shape, std::vector< unsigned long long > &write_start_address, std::vector< unsigned long long > &write_end_address, bool last_chunk_flag, std::vector< size_t > &prev_v_shape)
Insert output (vector of vector) into a buffer (vector) to write.
Definition: ft_output_vector.h:187
AuEndpointType
Definition: ft_type.h:95
@ EP_MEMORY
Definition: ft_type.h:101
@ EP_HDF5
Definition: ft_type.h:96
@ EP_DIR
Definition: ft_type.h:103
OutputVectorFlatDirection
Definition: ft_type.h:212
AuEndpointDataType
Definition: ft_type.h:118
@ AU_STRING
Definition: ft_type.h:131
int ExtractEndpointTypeInfo(std::string endpoint_type_info, AuEndpointType &endpoint_type, std::string &endpoint_info)
Split endpoint_type_info string to type and information.
Definition: ft_utility.cpp:100
void * ExtractAttributeFromVirtualArrayVector(std::vector< T2 > &virtual_array_vector, int attribute_index, AuEndpointDataType element_type, int element_type_size)
Definition: ft_utility.h:403
void PrintVector(std::string name, std::vector< T > v)
Definition: ft_utility.h:165
std::vector< unsigned long long > RowMajorOrderReverse(unsigned long long offset, std::vector< unsigned long long > dsize)
convert linearized coordinate to multidimensional one
Definition: ft_utility.h:276
void InsertAttribute2VirtualArrayVector(const std::vector< T1 > &attribute_vector, AuEndpointDataType union_index, std::vector< T2 > &virtual_array_vector, int attribute_index)
Definition: ft_utility.h:303
void PrintScalar(std::string name, T v)
Definition: ft_utility.h:237
#define ROW_MAJOR_ORDER_REVERSE_MACRO(offset, dsize, dsize_len, result_coord_v)
Definition: ft_utility_macro.h:135
#define ROW_MAJOR_ORDER_MACRO(dsize, dsize_len, coordinate, offset)
macro version of above two functions for speed
Definition: ft_utility_macro.h:124
#define AU_EXIT(info)
Definition: ft_utility_macro.h:147
#define COUNT_CELLS(start_address_p, end_address_p, cells_count_p)
help function to counts cells between start/end
Definition: ft_utility_macro.h:92
FTVisType
Definition: ft_vis.h:84
@ FT_VIS_XDMF
Definition: ft_vis.h:86
Definition: ft_array.h:113