11using Microsoft . ML . OnnxRuntime . Tensors ;
2- using OnnxStack . StableDiffusion . Config ;
32using System ;
43using System . Linq ;
54
65namespace OnnxStack . StableDiffusion . Helpers
76{
87 public static class TensorHelper
98 {
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>
1016 public static DenseTensor < T > CreateTensor < T > ( T [ ] data , ReadOnlySpan < int > dimensions )
1117 {
1218 return new DenseTensor < T > ( data , dimensions ) ;
1319 }
1420
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 )
1630 {
1731 var divTensor = new DenseTensor < float > ( dimensions ) ;
18- for ( int i = 0 ; i < data . Length ; i ++ )
32+ for ( int i = 0 ; i < tensor . Length ; i ++ )
1933 {
20- divTensor . SetValue ( i , data . GetValue ( i ) / value ) ;
34+ divTensor . SetValue ( i , tensor . GetValue ( i ) / value ) ;
2135 }
2236 return divTensor ;
2337 }
2438
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 )
2647 {
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 ++ )
2950 {
30- divTensor . SetValue ( i , data . GetValue ( i ) / value ) ;
51+ divTensor . SetValue ( i , tensor . GetValue ( i ) / value ) ;
3152 }
3253 return divTensor ;
3354 }
3455
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 )
3664 {
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 ++ )
3967 {
40- mullTensor . SetValue ( i , data . GetValue ( i ) * value ) ;
68+ mullTensor . SetValue ( i , tensor . GetValue ( i ) * value ) ;
4169 }
4270 return mullTensor ;
4371 }
4472
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 )
4681 {
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 ++ )
4984 {
50- addTensor . SetValue ( i , sample . GetValue ( i ) + sumTensor . GetValue ( i ) ) ;
85+ addTensor . SetValue ( i , tensor . GetValue ( i ) + sumTensor . GetValue ( i ) ) ;
5186 }
5287 return addTensor ;
5388 }
5489
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 )
56100 {
57101 var tensor1 = new DenseTensor < float > ( dimensions ) ;
58102 var tensor2 = new DenseTensor < float > ( dimensions ) ;
@@ -64,21 +108,28 @@ public static Tuple<DenseTensor<float>, DenseTensor<float>> SplitTensor(this Den
64108 {
65109 for ( int l = 0 ; l < scaledWidth ; l ++ )
66110 {
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 ] ;
69113 }
70114 }
71115 }
72116 }
73117 return new Tuple < DenseTensor < float > , DenseTensor < float > > ( tensor1 , tensor2 ) ;
74118 }
75119
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 )
77128 {
78129 var sumTensor = new DenseTensor < float > ( dimensions ) ;
79- for ( int m = 0 ; m < tensorArray . Length ; m ++ )
130+ for ( int m = 0 ; m < tensors . Length ; m ++ )
80131 {
81- var tensorToSum = tensorArray [ m ] ;
132+ var tensorToSum = tensors [ m ] ;
82133 for ( var i = 0 ; i < tensorToSum . Length ; i ++ )
83134 {
84135 sumTensor . SetValue ( i , sumTensor . GetValue ( i ) + tensorToSum . GetValue ( i ) ) ;
@@ -87,51 +138,79 @@ public static DenseTensor<float> SumTensors(this DenseTensor<float>[] tensorArra
87138 return sumTensor ;
88139 }
89140
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 )
91149 {
92- var dupTensor = data . Concat ( data ) . ToArray ( ) ;
150+ var dupTensor = tensor . Concat ( tensor ) . ToArray ( ) ;
93151 return CreateTensor ( dupTensor , dimensions ) ;
94152 }
95153
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 )
97163 {
98164 var result = new DenseTensor < float > ( dimensions ) ;
99- for ( var i = 0 ; i < sample . Length ; i ++ )
165+ for ( var i = 0 ; i < tensor . Length ; i ++ )
100166 {
101- result . SetValue ( i , sample . GetValue ( i ) - subTensor . GetValue ( i ) ) ;
167+ result . SetValue ( i , tensor . GetValue ( i ) - subTensor . GetValue ( i ) ) ;
102168 }
103169 return result ;
104170 }
105171
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 )
107180 {
108- return sample . SubtractTensors ( subTensor , sample . Dimensions ) ;
181+ return tensor . SubtractTensors ( subTensor , tensor . Dimensions ) ;
109182 }
110183
111184
112-
113185 /// <summary>
114186 /// Reorders the tensor.
115187 /// </summary>
116- /// <param name="inputTensor ">The input tensor.</param>
188+ /// <param name="tensor ">The input tensor.</param>
117189 /// <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 )
119191 {
120192 //reorder from batch channel height width to batch height width channel
121193 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 ++ )
123195 {
124- for ( int x = 0 ; x < inputTensor . Dimensions [ 3 ] ; x ++ )
196+ for ( int x = 0 ; x < tensor . Dimensions [ 3 ] ; x ++ )
125197 {
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 ] ;
129201 }
130202 }
131203 return inputImagesTensor ;
132204 }
133205
134206
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>
135214 public static DenseTensor < float > PerformGuidance ( this DenseTensor < float > noisePred , DenseTensor < float > noisePredText , double guidanceScale )
136215 {
137216 for ( int i = 0 ; i < noisePred . Dimensions [ 0 ] ; i ++ )
@@ -151,16 +230,47 @@ public static DenseTensor<float> PerformGuidance(this DenseTensor<float> noisePr
151230 }
152231
153232
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>
154240 public static DenseTensor < float > Clip ( this DenseTensor < float > tensor , float minValue , float maxValue )
155241 {
242+ var clipTensor = new DenseTensor < float > ( tensor . Dimensions ) ;
156243 for ( int i = 0 ; i < tensor . Length ; i ++ )
157244 {
158- tensor . SetValue ( i , Math . Clamp ( tensor . GetValue ( i ) , minValue , maxValue ) ) ;
245+ clipTensor . SetValue ( i , Math . Clamp ( tensor . GetValue ( i ) , minValue , maxValue ) ) ;
159246 }
160- return tensor ;
247+ return clipTensor ;
161248 }
162249
163250
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>
164274 public static DenseTensor < float > GetRandomTensor ( Random random , ReadOnlySpan < int > dimensions , float initNoiseSigma = 1f )
165275 {
166276 var latents = new DenseTensor < float > ( dimensions ) ;
0 commit comments