GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/PTensor.h Lines: 52 58 89.7 %
Date: 2026-03-27 22:08:32 Branches: 29 42 69.0 %

Line Branch Exec Source
1
/***************************************
2
	Auteur : Pierre Aubert
3
	Mail : pierre.aubert@lapp.in2p3.fr
4
	Licence : CeCILL-C
5
****************************************/
6
7
#ifndef __PTENSOR_H__
8
#define __PTENSOR_H__
9
10
#include <stdio.h>
11
#include "data_all.h"
12
#include "template_alloc.h"
13
#include "reshuffle_tensor.h"
14
#include "phoenix_assume_aligned.h"
15
#include "phoenix_transpose.h"
16
17
template<typename T>
18
class PBlock;
19
20
///@brief Deal with general tensor, allocation and other stuff
21
template<typename T>
22
class PTensor{
23
	public:
24
		PTensor(AllocMode::AllocMode allocMode, size_t nbElement);
25
		PTensor(AllocMode::AllocMode allocMode, size_t nbRow, size_t nbCol);
26
		PTensor(AllocMode::AllocMode allocMode, size_t nbSlice, size_t nbRow, size_t nbCol);
27
		PTensor(AllocMode::AllocMode allocMode = AllocMode::NONE, const size_t * tabShape = NULL, size_t nbDim = 0lu);
28
		PTensor(const PTensor<T> & other);
29
		virtual ~PTensor();
30
		PTensor & operator = (const PTensor<T> & other);
31
32
		bool reserve(const size_t * tabDim, size_t nbDim);
33
		bool resize(const size_t * tabDim, size_t nbDim);
34
35
		bool reserve(AllocMode::AllocMode allocMode, const size_t * tabDim, size_t nbDim);
36
		bool resize(AllocMode::AllocMode allocMode, const size_t * tabDim, size_t nbDim);
37
38
		bool resize(AllocMode::AllocMode allocMode, size_t nbValue);
39
		bool resize(AllocMode::AllocMode allocMode, size_t nbRow, size_t nbCol);
40
		bool resize(AllocMode::AllocMode allocMode, size_t nbSlice, size_t nbRow, size_t nbCol);
41
42
		bool fromFile(const std::string & fileName, AllocMode::AllocMode allocMode = AllocMode::NONE);
43
44
		void setAllocMode(AllocMode::AllocMode allocMode);
45
46
		void copyPointer(T * tabData, size_t * tabDim, size_t nbDim, bool isAligned, size_t padding);
47
48
		void fill(T value);
49
		void setData(const T * tabValue, size_t nbValue);
50
		void setData(const T * tabValue, size_t nbRow, size_t nbCol);
51
52
		void setValue(size_t index, T value);
53
		void setValue(size_t indexRow, size_t indexCol, T value);
54
55
		void setPaddingValue(T value);
56
		T getPaddingValue() const;
57
58
		void setNbVecNeighbour(size_t nbNeighbour);
59
		size_t getNbVecNeighbour() const;
60
61
		void fromScalToVecNeigbhour(const PTensor<T> & tensorScal);
62
		void fromScalToVecNeigbhour(const PTensor<T> & tensorScal, size_t vectorSize);
63
		void fromVecToScalNeigbhour(const PTensor<T> & tensorVec);
64
		void updateDupplicateVecNeighbour();
65
66
		void splitBlock(std::vector<PBlock<T> > & vecBlock, size_t blockSizeRow, size_t blockSizeCol, size_t neighborRing = 0lu) const;
67
		void mergeBlock(const std::vector<PBlock<T> > & vecBlock, size_t neighborRing = 0lu);
68
69
		void splitBlockLink(std::vector<PBlock<T> > & vecBlock, size_t blockSizeRow, size_t blockSizeCol, size_t neighborRing = 0lu) const;
70
71
		size_t getNbDim() const;
72
		size_t getFullSize() const;
73
		size_t getPadding() const;
74
		bool isAligned() const;
75
		size_t getNbCol() const;
76
		size_t getFullNbRow() const;
77
78
		AllocMode::AllocMode getAllocMode() const;
79
80
		const size_t * getShape() const;
81
		const T * getData() const;
82
		T * getData();
83
84
		const T & getValue(size_t index) const;
85
		T & getValue(size_t index);
86
87
		const T & getValue(size_t indexRow, size_t indexCol) const;
88
		T & getValue(size_t indexRow, size_t indexCol);
89
90
		///Opérator [] to get an element of the tensor
91
		/**	@param i : index of the element to be returned
92
		* 	@return i-th element of the tensor
93
		*/
94
		T & operator[] (size_t i){return p_tabData[i];}
95
96
		///Opérator [] to get an element of the tensor
97
		/**	@param i : index of the element to be returned
98
		* 	@return i-th element of the tensor
99
		*/
100
		const T & operator[] (size_t i) const{return p_tabData[i];}
101
102
		///Print the PTensor
103
		/**	@param other : PTensor to be printed
104
		 * 	@param[out] out : stream to be modified
105
		 * 	@return modified stream
106
		*/
107
158
		friend std::ostream & operator << (std::ostream & out, const PTensor<T> & other){
108
158
			out << "PTensor[nbDimension = "<<other.p_nbDimension<<", padding = "<<other.p_padding<<"](";
109
158
			if(other.p_shape != NULL){
110
474
				for(size_t i(0lu); i < other.p_nbDimension; ++i){
111
316
					if(i != 0lu){out << ", ";}
112
316
					out << other.p_shape[i];
113
				}
114
158
				out <<"]{";
115

158
				if(other.p_tabData != NULL && other.p_fullSize != 0lu){
116
158
					out << std::endl;
117
158
					size_t rowSize(other.p_nbCol + other.p_padding);
118
2062
					for(size_t i(0lu); i < other.p_fullNbRow; ++i){
119
1904
						out << "\t[";
120
105401
						for(size_t j(0lu); j < other.p_nbCol; ++j){
121
103497
							if(j != 0lu){out << ", ";}
122
103497
							out << other.p_tabData[i*rowSize + j];
123
						}
124
1904
						out << "]" << std::endl;
125
					}
126
158
					out << std::endl << "}" << std::endl;
127
				}else{
128
					out << "}";
129
				}
130
			}else{out << "NULL]{}";}
131
158
			return out;
132
		}
133
134
		///Save the current PTensor in a stream
135
		/**	@param[out] ds : stream to be used
136
		 * 	@return true on success, false otherwise
137
		*/
138
		template<typename Stream>
139
2310
		bool writeStream(Stream & ds){
140
			//Save the number of dimension of the tensor
141
2310
			bool b = DataStream<Stream, DataStreamMode::WRITE, size_t>::data_stream(ds, p_nbDimension);
142

2310
			if(p_nbDimension == 0lu || !b){return b;}		//If there is no dimension, quit now
143
			//Then save the dimension size
144
2310
			b &= DataStream<Stream, DataStreamMode::WRITE, size_t>::data_stream(ds, p_shape, p_nbDimension);
145
			//Save the alloc mode (do NOT remove the temporary, or you have to specialised a DataStream for the AllocMode::AllocMode)
146
2310
			int tmpAllocMode((int)p_allocMode);
147
2310
			b &= DataStream<Stream,DataStreamMode::WRITE, int>::data_stream(ds, tmpAllocMode);
148
2310
			b &= DataStream<Stream,DataStreamMode::WRITE, size_t>::data_stream(ds, p_nbNeighbour);
149
2310
			b &= DataStream<Stream,DataStreamMode::WRITE, size_t>::data_stream(ds, p_nbScalRow);
150
			//If the data type is a simple data, then we save it with a fast way
151
2310
			if(data_stream_isSimpleType<T>()){
152
2310
				if(p_padding == 0lu){		//If there is not padding, we save all at once
153
1848
					b &= DataStream<Stream,DataStreamMode::WRITE, T>::data_stream(ds, p_tabData, p_fullSize);
154
				}else{				//If there is a padding, we save row by row
155
462
					size_t rowSize(p_nbCol + p_padding);
156

79156
					for(size_t i(0lu); i < p_fullNbRow && b; ++i){
157
78694
						b &= DataStream<Stream,DataStreamMode::WRITE, T>::data_stream(ds, p_tabData + i*rowSize, p_nbCol);
158
					}
159
				}
160
			}else{	//If it is not a simple type, we save it element per element
161
				for(size_t i(0lu); i < p_fullSize && b; ++i){
162
					b &= DataStream<Stream,DataStreamMode::WRITE, T>::data_stream(ds, p_tabData[i]);
163
				}
164
			}
165
2310
			return true;
166
		}
167
168
		///Load the current PTensor with a stream
169
		/**	@param[out] ds : stream to be used
170
		 * 	@return true on success, false otherwise
171
		*/
172
		template<typename Stream>
173
660
		bool readStream(Stream & ds){
174
			//Get the number of dimensions
175
660
			size_t nbDimension(0lu);
176
660
			bool b = DataStream<Stream,DataStreamMode::READ, size_t>::data_stream(ds, nbDimension);
177
660
			if(nbDimension == 0lu || !b){return b;}		//If there is no dimension, quit now
178
			//Load the dimension size
179
660
			size_t * tabDimension = new size_t[nbDimension];
180
660
			b &= DataStream<Stream,DataStreamMode::READ, size_t>::data_stream(ds, tabDimension, nbDimension);
181
			//Get the alloc mode (do NOT remove the temporary, or you have to specialised a DataStream for the AllocMode::AllocMode)
182
660
			int tmpAllocMode(0);
183
660
			b &= DataStream<Stream,DataStreamMode::READ, int>::data_stream(ds, tmpAllocMode);
184
660
			p_allocMode = (AllocMode::AllocMode)tmpAllocMode;
185
660
			b &= DataStream<Stream,DataStreamMode::READ, size_t>::data_stream(ds, p_nbNeighbour);
186
660
			b &= DataStream<Stream,DataStreamMode::READ, size_t>::data_stream(ds, p_nbScalRow);
187
			//Some relevant function call
188
660
			resize(tabDimension, nbDimension);
189
190
			//If the data type is a simple data, then we load it with a fast way
191
660
			if(data_stream_isSimpleType<T>()){
192
660
				if(p_padding == 0lu){		//If there is not padding, we save all at once
193
528
					b &= DataStream<Stream,DataStreamMode::READ, T>::data_stream(ds, p_tabData, p_fullSize);
194
				}else{				//If there is a padding, we load row by row
195
132
					size_t rowSize(p_nbCol + p_padding);
196
22616
					for(size_t i(0lu); i < p_fullNbRow && b; ++i){
197
22484
						b &= DataStream<Stream,DataStreamMode::READ, T>::data_stream(ds, p_tabData + i*rowSize, p_nbCol);
198
					}
199
				}
200
			}else{	//If it is not a simple type, we load it element per element
201
				for(size_t i(0lu); i < p_fullSize && b; ++i){
202
					b &= DataStream<Stream,DataStreamMode::READ, T>::data_stream(ds, p_tabData[i]);
203
				}
204
			}
205
660
			return true;
206
		}
207
208
	protected:
209
		void copyPTensor(const PTensor<T> & other);
210
		///Number of dimension of the PTensor
211
		size_t p_nbDimension;
212
213
	private:
214
		void initialisationPTensor(AllocMode::AllocMode allocMode, const size_t * tabShape, size_t nbDim);
215
		void freeTabData();
216
217
		void copyTensorToBlock(PBlock<T> & block, size_t tensorNbCol, size_t blockSizeRow, size_t blockSizeCol,
218
					size_t fullBlockSizeRow, size_t fullBlockSizeCol, size_t i, size_t j, size_t neighborRing) const;
219
		void linkTensorToBlock(PBlock<T> & block, size_t tensorNbCol, size_t blockSizeRow, size_t blockSizeCol,
220
					size_t fullBlockSizeRow, size_t fullBlockSizeCol, size_t i, size_t j, size_t neighborRing) const;
221
		void updateBlockSize(size_t & nbTotalBlock, size_t & nbInBlockRow, size_t & nbInBlockCol,
222
					size_t & sizeLastInBlockRow, size_t & sizeLastInBlockCol,
223
					std::vector<PBlock<T> > & vecBlock, size_t blockSizeRow, size_t & blockSizeCol, size_t neighborRing) const;
224
		///Table of data
225
		T* p_tabData;
226
227
		///Size of each dimension of the PTensor
228
		size_t* p_shape;
229
		///Full number of elements of the tensor
230
		size_t p_fullSize;
231
		///Full number of elements of the tensor taking account the padding
232
		size_t p_fullPaddedSize;
233
		///Number of element on the last dimension of the PTensor
234
		size_t p_nbCol;
235
		///Full number of rows (including all dimensions except the very last one)
236
		size_t p_fullNbRow;
237
		///Number of elements which are neighbours together with the next ones (scalar: 1, vectorial: n)
238
		size_t p_nbNeighbour;
239
		///Number of rows in scalar mode
240
		size_t p_nbScalRow;
241
242
		///Reserved number of dimension of the PTensor
243
		size_t p_reservedNbDimension;
244
		///Reserved size of each dimension of the PTensor
245
		size_t* p_reservedShape;
246
247
		///Padding of the PTensor
248
		size_t p_padding;
249
		///True if the PTensor is aligned, false otherwise
250
		bool p_isAligned;
251
		///Allocation mode
252
		AllocMode::AllocMode p_allocMode;
253
		///True if the PTensor own the shape and data pointers
254
		bool p_isOwnData;
255
};
256
257
AllocMode::AllocMode tensor_getAllocMode(bool isAligned, size_t padding);
258
void splitBlockSize(size_t & nbInBlockRow, size_t & sizeLastInBlockRow, size_t & blockSizeRow, size_t nbRow, size_t neighborRing, size_t vectorNeigbour);
259
260
#include "PTensor_impl.h"
261
#include "PBlock.h"
262
263
#endif
264