1
1
using Microsoft . ML . OnnxRuntime . Tensors ;
2
- using OnnxStack . StableDiffusion . Config ;
3
2
using System ;
4
3
using System . Linq ;
5
4
6
5
namespace OnnxStack . StableDiffusion . Helpers
7
6
{
8
7
public static class TensorHelper
9
8
{
9
+ /// <summary>
10
+ /// Creates a new tensor.
11
+ /// </summary>
12
+ /// <typeparam name="T"></typeparam>
13
+ /// <param name="data">The data.</param>
14
+ /// <param name="dimensions">The dimensions.</param>
15
+ /// <returns></returns>
10
16
public static DenseTensor < T > CreateTensor < T > ( T [ ] data , ReadOnlySpan < int > dimensions )
11
17
{
12
18
return new DenseTensor < T > ( data , dimensions ) ;
13
19
}
14
20
15
- public static DenseTensor < float > DivideTensorByFloat ( this DenseTensor < float > data , float value , ReadOnlySpan < int > dimensions )
21
+
22
+ /// <summary>
23
+ /// Divides the tensor by float.
24
+ /// </summary>
25
+ /// <param name="tensor">The data.</param>
26
+ /// <param name="value">The value.</param>
27
+ /// <param name="dimensions">The dimensions.</param>
28
+ /// <returns></returns>
29
+ public static DenseTensor < float > DivideTensorByFloat ( this DenseTensor < float > tensor , float value , ReadOnlySpan < int > dimensions )
16
30
{
17
31
var divTensor = new DenseTensor < float > ( dimensions ) ;
18
- for ( int i = 0 ; i < data . Length ; i ++ )
32
+ for ( int i = 0 ; i < tensor . Length ; i ++ )
19
33
{
20
- divTensor . SetValue ( i , data . GetValue ( i ) / value ) ;
34
+ divTensor . SetValue ( i , tensor . GetValue ( i ) / value ) ;
21
35
}
22
36
return divTensor ;
23
37
}
24
38
25
- public static DenseTensor < float > DivideTensorByFloat ( this DenseTensor < float > data , float value )
39
+
40
+ /// <summary>
41
+ /// Divides the tensor by float.
42
+ /// </summary>
43
+ /// <param name="tensor">The data.</param>
44
+ /// <param name="value">The value.</param>
45
+ /// <returns></returns>
46
+ public static DenseTensor < float > DivideTensorByFloat ( this DenseTensor < float > tensor , float value )
26
47
{
27
- var divTensor = new DenseTensor < float > ( data . Dimensions ) ;
28
- for ( int i = 0 ; i < data . Length ; i ++ )
48
+ var divTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
49
+ for ( int i = 0 ; i < tensor . Length ; i ++ )
29
50
{
30
- divTensor . SetValue ( i , data . GetValue ( i ) / value ) ;
51
+ divTensor . SetValue ( i , tensor . GetValue ( i ) / value ) ;
31
52
}
32
53
return divTensor ;
33
54
}
34
55
35
- public static DenseTensor < float > MultipleTensorByFloat ( this DenseTensor < float > data , float value )
56
+
57
+ /// <summary>
58
+ /// Multiples the tensor by float.
59
+ /// </summary>
60
+ /// <param name="tensor">The data.</param>
61
+ /// <param name="value">The value.</param>
62
+ /// <returns></returns>
63
+ public static DenseTensor < float > MultipleTensorByFloat ( this DenseTensor < float > tensor , float value )
36
64
{
37
- var mullTensor = new DenseTensor < float > ( data . Dimensions ) ;
38
- for ( int i = 0 ; i < data . Length ; i ++ )
65
+ var mullTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
66
+ for ( int i = 0 ; i < tensor . Length ; i ++ )
39
67
{
40
- mullTensor . SetValue ( i , data . GetValue ( i ) * value ) ;
68
+ mullTensor . SetValue ( i , tensor . GetValue ( i ) * value ) ;
41
69
}
42
70
return mullTensor ;
43
71
}
44
72
45
- public static DenseTensor < float > AddTensors ( this DenseTensor < float > sample , DenseTensor < float > sumTensor )
73
+
74
+ /// <summary>
75
+ /// Adds the tensors.
76
+ /// </summary>
77
+ /// <param name="tensor">The sample.</param>
78
+ /// <param name="sumTensor">The sum tensor.</param>
79
+ /// <returns></returns>
80
+ public static DenseTensor < float > AddTensors ( this DenseTensor < float > tensor , DenseTensor < float > sumTensor )
46
81
{
47
- var addTensor = new DenseTensor < float > ( sample . Dimensions ) ;
48
- for ( var i = 0 ; i < sample . Length ; i ++ )
82
+ var addTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
83
+ for ( var i = 0 ; i < tensor . Length ; i ++ )
49
84
{
50
- addTensor . SetValue ( i , sample . GetValue ( i ) + sumTensor . GetValue ( i ) ) ;
85
+ addTensor . SetValue ( i , tensor . GetValue ( i ) + sumTensor . GetValue ( i ) ) ;
51
86
}
52
87
return addTensor ;
53
88
}
54
89
55
- public static Tuple < DenseTensor < float > , DenseTensor < float > > SplitTensor ( this DenseTensor < float > tensorToSplit , ReadOnlySpan < int > dimensions , int scaledHeight , int scaledWidth )
90
+
91
+ /// <summary>
92
+ /// Splits the tensor.
93
+ /// </summary>
94
+ /// <param name="tensorToSplit">The tensor to split.</param>
95
+ /// <param name="dimensions">The dimensions.</param>
96
+ /// <param name="scaledHeight">Height of the scaled.</param>
97
+ /// <param name="scaledWidth">Width of the scaled.</param>
98
+ /// <returns></returns>
99
+ public static Tuple < DenseTensor < float > , DenseTensor < float > > SplitTensor ( this DenseTensor < float > tensor , ReadOnlySpan < int > dimensions , int scaledHeight , int scaledWidth )
56
100
{
57
101
var tensor1 = new DenseTensor < float > ( dimensions ) ;
58
102
var tensor2 = new DenseTensor < float > ( dimensions ) ;
@@ -64,21 +108,28 @@ public static Tuple<DenseTensor<float>, DenseTensor<float>> SplitTensor(this Den
64
108
{
65
109
for ( int l = 0 ; l < scaledWidth ; l ++ )
66
110
{
67
- tensor1 [ i , j , k , l ] = tensorToSplit [ i , j , k , l ] ;
68
- tensor2 [ i , j , k , l ] = tensorToSplit [ i , j + 4 , k , l ] ;
111
+ tensor1 [ i , j , k , l ] = tensor [ i , j , k , l ] ;
112
+ tensor2 [ i , j , k , l ] = tensor [ i , j + 4 , k , l ] ;
69
113
}
70
114
}
71
115
}
72
116
}
73
117
return new Tuple < DenseTensor < float > , DenseTensor < float > > ( tensor1 , tensor2 ) ;
74
118
}
75
119
76
- public static DenseTensor < float > SumTensors ( this DenseTensor < float > [ ] tensorArray , ReadOnlySpan < int > dimensions )
120
+
121
+ /// <summary>
122
+ /// Sums the tensors.
123
+ /// </summary>
124
+ /// <param name="tensors">The tensor array.</param>
125
+ /// <param name="dimensions">The dimensions.</param>
126
+ /// <returns></returns>
127
+ public static DenseTensor < float > SumTensors ( this DenseTensor < float > [ ] tensors , ReadOnlySpan < int > dimensions )
77
128
{
78
129
var sumTensor = new DenseTensor < float > ( dimensions ) ;
79
- for ( int m = 0 ; m < tensorArray . Length ; m ++ )
130
+ for ( int m = 0 ; m < tensors . Length ; m ++ )
80
131
{
81
- var tensorToSum = tensorArray [ m ] ;
132
+ var tensorToSum = tensors [ m ] ;
82
133
for ( var i = 0 ; i < tensorToSum . Length ; i ++ )
83
134
{
84
135
sumTensor . SetValue ( i , sumTensor . GetValue ( i ) + tensorToSum . GetValue ( i ) ) ;
@@ -87,51 +138,79 @@ public static DenseTensor<float> SumTensors(this DenseTensor<float>[] tensorArra
87
138
return sumTensor ;
88
139
}
89
140
90
- public static DenseTensor < float > Duplicate ( this DenseTensor < float > data , ReadOnlySpan < int > dimensions )
141
+
142
+ /// <summary>
143
+ /// Duplicates the specified tensor.
144
+ /// </summary>
145
+ /// <param name="tensor">The data.</param>
146
+ /// <param name="dimensions">The dimensions.</param>
147
+ /// <returns></returns>
148
+ public static DenseTensor < float > Duplicate ( this DenseTensor < float > tensor , ReadOnlySpan < int > dimensions )
91
149
{
92
- var dupTensor = data . Concat ( data ) . ToArray ( ) ;
150
+ var dupTensor = tensor . Concat ( tensor ) . ToArray ( ) ;
93
151
return CreateTensor ( dupTensor , dimensions ) ;
94
152
}
95
153
96
- public static DenseTensor < float > SubtractTensors ( this DenseTensor < float > sample , DenseTensor < float > subTensor , ReadOnlySpan < int > dimensions )
154
+
155
+ /// <summary>
156
+ /// Subtracts the tensors.
157
+ /// </summary>
158
+ /// <param name="tensor">The tensor.</param>
159
+ /// <param name="subTensor">The sub tensor.</param>
160
+ /// <param name="dimensions">The dimensions.</param>
161
+ /// <returns></returns>
162
+ public static DenseTensor < float > SubtractTensors ( this DenseTensor < float > tensor , DenseTensor < float > subTensor , ReadOnlySpan < int > dimensions )
97
163
{
98
164
var result = new DenseTensor < float > ( dimensions ) ;
99
- for ( var i = 0 ; i < sample . Length ; i ++ )
165
+ for ( var i = 0 ; i < tensor . Length ; i ++ )
100
166
{
101
- result . SetValue ( i , sample . GetValue ( i ) - subTensor . GetValue ( i ) ) ;
167
+ result . SetValue ( i , tensor . GetValue ( i ) - subTensor . GetValue ( i ) ) ;
102
168
}
103
169
return result ;
104
170
}
105
171
106
- public static DenseTensor < float > SubtractTensors ( this DenseTensor < float > sample , DenseTensor < float > subTensor )
172
+
173
+ /// <summary>
174
+ /// Subtracts the tensors.
175
+ /// </summary>
176
+ /// <param name="tensor">The sample.</param>
177
+ /// <param name="subTensor">The sub tensor.</param>
178
+ /// <returns></returns>
179
+ public static DenseTensor < float > SubtractTensors ( this DenseTensor < float > tensor , DenseTensor < float > subTensor )
107
180
{
108
- return sample . SubtractTensors ( subTensor , sample . Dimensions ) ;
181
+ return tensor . SubtractTensors ( subTensor , tensor . Dimensions ) ;
109
182
}
110
183
111
184
112
-
113
185
/// <summary>
114
186
/// Reorders the tensor.
115
187
/// </summary>
116
- /// <param name="inputTensor ">The input tensor.</param>
188
+ /// <param name="tensor ">The input tensor.</param>
117
189
/// <returns></returns>
118
- public static DenseTensor < float > ReorderTensor ( this DenseTensor < float > inputTensor , ReadOnlySpan < int > dimensions )
190
+ public static DenseTensor < float > ReorderTensor ( this DenseTensor < float > tensor , ReadOnlySpan < int > dimensions )
119
191
{
120
192
//reorder from batch channel height width to batch height width channel
121
193
var inputImagesTensor = new DenseTensor < float > ( dimensions ) ;
122
- for ( int y = 0 ; y < inputTensor . Dimensions [ 2 ] ; y ++ )
194
+ for ( int y = 0 ; y < tensor . Dimensions [ 2 ] ; y ++ )
123
195
{
124
- for ( int x = 0 ; x < inputTensor . Dimensions [ 3 ] ; x ++ )
196
+ for ( int x = 0 ; x < tensor . Dimensions [ 3 ] ; x ++ )
125
197
{
126
- inputImagesTensor [ 0 , y , x , 0 ] = inputTensor [ 0 , 0 , y , x ] ;
127
- inputImagesTensor [ 0 , y , x , 1 ] = inputTensor [ 0 , 1 , y , x ] ;
128
- inputImagesTensor [ 0 , y , x , 2 ] = inputTensor [ 0 , 2 , y , x ] ;
198
+ inputImagesTensor [ 0 , y , x , 0 ] = tensor [ 0 , 0 , y , x ] ;
199
+ inputImagesTensor [ 0 , y , x , 1 ] = tensor [ 0 , 1 , y , x ] ;
200
+ inputImagesTensor [ 0 , y , x , 2 ] = tensor [ 0 , 2 , y , x ] ;
129
201
}
130
202
}
131
203
return inputImagesTensor ;
132
204
}
133
205
134
206
207
+ /// <summary>
208
+ /// Performs classifier free guidance
209
+ /// </summary>
210
+ /// <param name="noisePred">The noise pred.</param>
211
+ /// <param name="noisePredText">The noise pred text.</param>
212
+ /// <param name="guidanceScale">The guidance scale.</param>
213
+ /// <returns></returns>
135
214
public static DenseTensor < float > PerformGuidance ( this DenseTensor < float > noisePred , DenseTensor < float > noisePredText , double guidanceScale )
136
215
{
137
216
for ( int i = 0 ; i < noisePred . Dimensions [ 0 ] ; i ++ )
@@ -151,16 +230,47 @@ public static DenseTensor<float> PerformGuidance(this DenseTensor<float> noisePr
151
230
}
152
231
153
232
233
+ /// <summary>
234
+ /// Clips the specified Tensor valuse to the specified minimum/maximum.
235
+ /// </summary>
236
+ /// <param name="tensor">The tensor.</param>
237
+ /// <param name="minValue">The minimum value.</param>
238
+ /// <param name="maxValue">The maximum value.</param>
239
+ /// <returns></returns>
154
240
public static DenseTensor < float > Clip ( this DenseTensor < float > tensor , float minValue , float maxValue )
155
241
{
242
+ var clipTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
156
243
for ( int i = 0 ; i < tensor . Length ; i ++ )
157
244
{
158
- tensor . SetValue ( i , Math . Clamp ( tensor . GetValue ( i ) , minValue , maxValue ) ) ;
245
+ clipTensor . SetValue ( i , Math . Clamp ( tensor . GetValue ( i ) , minValue , maxValue ) ) ;
159
246
}
160
- return tensor ;
247
+ return clipTensor ;
161
248
}
162
249
163
250
251
+ /// <summary>
252
+ /// Computes the absolute values of the Tensor
253
+ /// </summary>
254
+ /// <param name="tensor">The tensor.</param>
255
+ /// <returns></returns>
256
+ public static DenseTensor < float > Abs ( this DenseTensor < float > tensor )
257
+ {
258
+ var absTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
259
+ for ( int i = 0 ; i < tensor . Length ; i ++ )
260
+ {
261
+ absTensor . SetValue ( i , Math . Abs ( tensor . GetValue ( i ) ) ) ;
262
+ }
263
+ return absTensor ;
264
+ }
265
+
266
+
267
+ /// <summary>
268
+ /// Generate a random Tensor from a normal distribution with mean 0 and variance 1
269
+ /// </summary>
270
+ /// <param name="random">The random.</param>
271
+ /// <param name="dimensions">The dimensions.</param>
272
+ /// <param name="initNoiseSigma">The initialize noise sigma.</param>
273
+ /// <returns></returns>
164
274
public static DenseTensor < float > GetRandomTensor ( Random random , ReadOnlySpan < int > dimensions , float initNoiseSigma = 1f )
165
275
{
166
276
var latents = new DenseTensor < float > ( dimensions ) ;
0 commit comments