FasTensor  1.0.0
Transform Supercomputing for AI
ft_output_vector.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 #ifndef _AU_OUTPUT_VECTOR_H_
81 #define _AU_OUTPUT_VECTOR_H_
82 
83 #include <vector>
84 #include <type_traits>
85 #include <cstring>
86 #include <cmath>
87 #include <sys/types.h>
88 #include <sys/stat.h>
89 #include <unistd.h>
90 #include <tuple>
91 #include <string>
92 #include <sstream>
93 #include <algorithm>
94 #include <iterator>
95 #include <iostream>
96 #include <utility>
97 #include <variant>
98 #include <dirent.h>
99 
100 #include "ft_type.h"
101 #include "ft_utility_macro.h"
102 #include "ft_array_view_access.h"
113 inline void GetChunkAddress(const unsigned long long chunk_id, const std::vector<unsigned long long> array_size, const std::vector<size_t> chunk_size, std::vector<unsigned long long> &chunk_start_address, std::vector<unsigned long long> &chunk_end_address)
114 {
115  int rank = array_size.size();
116  //PrintScalar("rank = ", rank);
117  //PrintVector("array_size = ", array_size);
118  //PrintVector("chunk_size = ", chunk_size);
119 
120  std::vector<unsigned long long> chunks;
121  unsigned long long total_chunks = 1;
122  chunks.resize(rank);
123 
124  for (int i = 0; i < rank; i++)
125  {
126  if (array_size[i] % chunk_size[i] == 0)
127  {
128  chunks[i] = array_size[i] / chunk_size[i];
129  }
130  else
131  {
132  chunks[i] = array_size[i] / chunk_size[i] + 1;
133  }
134  total_chunks = chunks[i] * total_chunks;
135  }
136 
137  if (chunk_id >= total_chunks)
138  {
139  AU_EXIT("chunk_id >= total_chunks: chunk_id =" + std::to_string(chunk_id) + ", total_chunks = " + std::to_string(total_chunks));
140  }
141  std::vector<unsigned long long> chunk_coordinate(rank);
142  //PrintVector("chunks = ", chunks);
143  //PrintScalar("chunk_id = ", chunk_id);
144  //PrintVector("chunk_coordinate = ", chunk_coordinate);
145 
146  ROW_MAJOR_ORDER_REVERSE_MACRO(chunk_id, chunks, rank, chunk_coordinate);
147 
148  chunk_start_address.resize(rank);
149  chunk_end_address.resize(rank);
150  for (int i = 0; i < rank; i++)
151  {
152 
153  if (chunk_coordinate[i] * chunk_size[i] < array_size[i])
154  {
155  chunk_start_address[i] = chunk_coordinate[i] * chunk_size[i];
156  }
157  else
158  {
159  chunk_start_address[i] = array_size[i];
160  }
161 
162  if (chunk_start_address[i] + chunk_size[i] - 1 < array_size[i])
163  {
164  chunk_end_address[i] = chunk_start_address[i] + chunk_size[i] - 1;
165  }
166  else
167  {
168  chunk_end_address[i] = array_size[i] - 1;
169  }
170  }
171 
172  //PrintVector("chunk_start_address = ", chunk_start_address);
173  //PrintVector("chunk_end_address = ", chunk_end_address);
174 }
175 
186 template <typename T>
187 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)
188 {
189  //First to infer the size of the WriteVector from (write_end_address - write_start_address) and v_shape
190 
191  int rank = write_start_address.size();
192 
193  //We can only deal with one extra dimension
194  if (v_shape.size() > (rank + 1))
195  {
196  AU_INFO("Warning: the shape of output Stencil has more dimensions than current support !\n");
197  }
198 
199  std::vector<unsigned long long> write_vector_size;
200  unsigned long long write_vector_length = 1, temp_address;
201  for (int i = 0; i < v_shape.size(); i++)
202  {
203  if (i >= rank) //have extra dimension to deal with
204  {
205  write_start_address.push_back(0);
206  write_end_address.push_back(v_shape[i] - 1);
207  }
208  else
209  {
210  // write_start_address = 2 write_end_address = 3 v_shape = 2
211  // ==> write_start_address = 4 write_end_address = 7
212  temp_address = write_start_address[i];
213  if (last_chunk_flag)
214  {
215  write_start_address[i] = write_start_address[i] * prev_v_shape[i];
216  }
217  else
218  {
219  write_start_address[i] = write_start_address[i] * v_shape[i];
220  }
221  write_end_address[i] = write_start_address[i] + (write_end_address[i] - temp_address + 1) * v_shape[i] - 1;
222  }
223  //std::cout << write_end_address[i] << " ,, " << write_start_address[i] << "\n";
224  write_vector_size.push_back(write_end_address[i] - write_start_address[i] + 1);
225  write_vector_length = write_vector_length * write_vector_size[i];
226  }
227 
228  //update the rank to add new dimensions
229  rank = v_shape.size();
230 
231  T *rv = (T *)malloc(write_vector_length * sizeof(T));
232  //Now we have output vector with the shape write_vector_size and each element in v has the shape v_shape.
233  //we need to write the v into
234  //template <class T>
235  //inline int ArrayViewAccessP(T * view_v, T * array_v, std::vector<unsigned long long> ///array_size, std::vector<unsigned long long> start, std::vector<unsigned long long> end, int read_write_code)
236 
237  //PrintVector("v_shape = ", v_shape);
238  //PrintVector("write_vector_size = ", write_vector_size);
239  //PrintVector("write_start_address = ", write_start_address);
240  //PrintVector("write_end_address = ", write_end_address);
241 
242  std::vector<unsigned long long> view_start(rank), view_end(rank);
243  for (size_t i = 0; i < v.size(); i++)
244  {
245  GetChunkAddress(i, write_vector_size, v_shape, view_start, view_end);
246  ArrayViewAccessP(v[i].data(), rv, write_vector_size, view_start, view_end, ARRAY_VIEW_WRITE);
247  }
248 
249  return rv;
250 }
251 
252 template <typename T>
253 void *InsertOutputVV2WriteV(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)
254 {
255  AU_EXIT("This function should not be called !");
256 }
257 
258 template <typename T>
259 void *InsertOutputVV2WriteV(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)
260 {
261  AU_EXIT("This function should not be called !");
262 }
263 //
264 //Below are old code to delete
265 //
266 
296 template <typename T>
297 void *FlatVector(std::vector<std::vector<T>> &v, OutputVectorFlatDirection direction, std::vector<unsigned long long> &start_address, std::vector<unsigned long long> &end_address, size_t &v_size)
298 {
299  if (v.size() < 1)
300  {
301  return NULL;
302  }
303 
304  if (v[0].size() < 1)
305  {
306  return NULL;
307  }
308 
309  //Check v's elemtnt has same size
310  for (unsigned j = 0; j < v.size() - 1; j++)
311  {
312  if (v[j].size() != v[j + 1].size())
313  {
314  AU_EXIT("Size of each element of vector must be equal.");
315  }
316  }
317  v_size = v[0].size();
318 
319  if (direction == AU_FLAT_OUTPUT_NEW)
320  {
321  start_address.push_back(0);
322  end_address.push_back(v_size - 1);
323  return &v[0];
324  }
325 
326  T *rv = (T *)malloc(v.size() * v_size * sizeof(T)); //Assuming all rows have the same size
327  if (rv == NULL)
328  {
329  AU_EXIT("Not enough memory");
330  }
331 
332  if (direction == AU_FLAT_OUTPUT_COL)
333  {
334  for (unsigned i = 0; i < v_size; i++)
335  {
336  for (unsigned j = 0; j < v.size(); j++)
337  {
338  memcpy(rv + v.size() * i + j, &(v[j][i]), sizeof(T));
339  }
340  }
341  }
342  else if (direction == AU_FLAT_OUTPUT_ROW)
343  {
344 
345  for (unsigned i = 0; i < v.size(); i++)
346  {
347  memcpy(rv + v_size * i, &(v[i][0]), v_size * sizeof(T));
348  }
349  }
350  else
351  {
352  AU_EXIT("Not supported option yet to flat vector");
353  }
354 
355  end_address[direction] = start_address[direction] + (end_address[direction] - start_address[direction] + 1) * v_size - 1;
356 
357  return (void *)rv;
358 }
359 
360 template <typename T>
361 void *FlatVector(std::vector<T> &v, OutputVectorFlatDirection direction, std::vector<unsigned long long> &start_address, std::vector<unsigned long long> &end_address, size_t &v_size)
362 {
363  AU_EXIT("Should not be here");
364 }
365 
366 template <typename T>
367 void *FlatVector(T &v, OutputVectorFlatDirection direction, std::vector<unsigned long long> &start_address, std::vector<unsigned long long> &end_address, size_t &v_size)
368 {
369  AU_EXIT("Should not be here");
370 }
371 
372 #endif
int ArrayViewAccessP(T *view_v, T *array_v, std::vector< unsigned long long > array_size, std::vector< unsigned long long > start, std::vector< unsigned long long > end, int read_write_code)
Definition: ft_array_view_access.h:195
#define ARRAY_VIEW_WRITE
Definition: ft_array_view_access.h:90
void * FlatVector(std::vector< std::vector< T >> &v, OutputVectorFlatDirection direction, std::vector< unsigned long long > &start_address, std::vector< unsigned long long > &end_address, size_t &v_size)
flat vector of vector to 1D vector direction specify row-major or colum major AU_FLAT_OUTPUT_ROW (0):...
Definition: ft_output_vector.h:297
void GetChunkAddress(const unsigned long long chunk_id, const std::vector< unsigned long long > array_size, const std::vector< size_t > chunk_size, std::vector< unsigned long long > &chunk_start_address, std::vector< unsigned long long > &chunk_end_address)
Get the Chunk Address object.
Definition: ft_output_vector.h:113
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
OutputVectorFlatDirection
Definition: ft_type.h:212
@ AU_FLAT_OUTPUT_COL
Definition: ft_type.h:213
@ AU_FLAT_OUTPUT_ROW
Definition: ft_type.h:214
@ AU_FLAT_OUTPUT_NEW
Definition: ft_type.h:215
#define ROW_MAJOR_ORDER_REVERSE_MACRO(offset, dsize, dsize_len, result_coord_v)
Definition: ft_utility_macro.h:135
#define AU_EXIT(info)
Definition: ft_utility_macro.h:147
#define AU_INFO(info)
Definition: ft_utility_macro.h:154