xref: /aosp_15_r20/external/executorch/extension/tensor/tensor_ptr_maker.h (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #pragma once
10 
11 #include <executorch/extension/tensor/tensor_ptr.h>
12 
13 namespace executorch {
14 namespace extension {
15 
16 /**
17  * A helper class for creating TensorPtr instances from raw data and tensor
18  * properties. Note that the TensorPtr created by this class does not own the
19  * data, so the data must outlive the TensorPtr.
20  *
21  * TensorPtrMaker provides a fluent interface for specifying various tensor
22  * properties, such as type, sizes, data pointer, dimension order, strides, and
23  * shape dynamism. The final tensor is created by invoking make_tensor_ptr() or
24  * by converting TensorPtrMaker to TensorPtr.
25  */
26 class TensorPtrMaker final {
27  public:
28   // This class may have non-copyable members in the future.
29   TensorPtrMaker(const TensorPtrMaker&) = delete;
30   TensorPtrMaker& operator=(const TensorPtrMaker&) = delete;
31   // But it is movable.
32   TensorPtrMaker(TensorPtrMaker&&) = default;
33   TensorPtrMaker& operator=(TensorPtrMaker&&) = default;
34 
35   /**
36    * Sets the scalar type of the tensor elements.
37    *
38    * @param type The scalar type (e.g., float, int, bool).
39    * @return Rvalue to this TensorPtrMaker for method chaining.
40    */
type(executorch::aten::ScalarType type)41   TensorPtrMaker&& type(executorch::aten::ScalarType type) {
42     type_ = type;
43     return std::move(*this);
44   }
45 
46   /**
47    * Sets the order of dimensions in memory.
48    *
49    * @param dim_order A vector specifying the dimension order.
50    * @return Rvalue to this TensorPtrMaker for method chaining.
51    */
dim_order(std::vector<executorch::aten::DimOrderType> dim_order)52   TensorPtrMaker&& dim_order(
53       std::vector<executorch::aten::DimOrderType> dim_order) {
54     dim_order_ = std::move(dim_order);
55     return std::move(*this);
56   }
57 
58   /**
59    * Sets the strides for each dimension of the tensor.
60    *
61    * @param strides A vector specifying the stride for each dimension.
62    * @return Rvalue to this TensorPtrMaker for method chaining.
63    */
strides(std::vector<executorch::aten::StridesType> strides)64   TensorPtrMaker&& strides(std::vector<executorch::aten::StridesType> strides) {
65     strides_ = std::move(strides);
66     return std::move(*this);
67   }
68 
69   /**
70    * Sets the shape dynamism of the tensor.
71    *
72    * @param dynamism Specifies whether the tensor's shape is static, dynamic, or
73    * bounded.
74    * @return Rvalue to this TensorPtrMaker for method chaining.
75    */
dynamism(executorch::aten::TensorShapeDynamism dynamism)76   TensorPtrMaker&& dynamism(executorch::aten::TensorShapeDynamism dynamism) {
77     dynamism_ = dynamism;
78     return std::move(*this);
79   }
80 
81   /**
82    * Sets a custom deleter function to manage the lifetime of the data buffer.
83    *
84    * @param deleter A function that will be called to delete the data buffer
85    * when the Tensor object managed by the TensorPtr is destroyed. Explicitly
86    * consuming an rvalue to avoid unnecessary copies when the deleter is a
87    * lambda that has captured some state.
88    * @return Rvalue to this TensorPtrMaker for method chaining.
89    */
deleter(std::function<void (void *)> && deleter)90   TensorPtrMaker&& deleter(std::function<void(void*)>&& deleter) {
91     deleter_ = std::move(deleter);
92     return std::move(*this);
93   }
94 
95   /**
96    * Creates and returns a TensorPtr instance using the properties set in this
97    * TensorPtrMaker.
98    *
99    * @return A TensorPtr instance that manages the newly created Tensor.
100    */
make_tensor_ptr()101   TensorPtr make_tensor_ptr() && {
102     return ::executorch::extension::make_tensor_ptr(
103         std::move(sizes_),
104         data_,
105         std::move(dim_order_),
106         std::move(strides_),
107         type_,
108         dynamism_,
109         std::move(deleter_));
110   }
111 
112   /**
113    * Implicit conversion operator to create a TensorPtr.
114    *
115    * @return A TensorPtr instance that manages the newly created Tensor.
116    */
TensorPtr()117   operator TensorPtr() && {
118     return std::move(*this).make_tensor_ptr();
119   }
120 
121  private:
TensorPtrMaker(void * data,std::vector<executorch::aten::SizesType> sizes,executorch::aten::ScalarType type)122   TensorPtrMaker(
123       void* data,
124       std::vector<executorch::aten::SizesType> sizes,
125       executorch::aten::ScalarType type)
126       : sizes_(std::move(sizes)), data_(data), type_(type) {}
127 
128  private:
129   // The following properties are required to create a Tensor.
130   friend TensorPtrMaker for_blob(
131       void* data,
132       std::vector<executorch::aten::SizesType> sizes,
133       executorch::aten::ScalarType type);
134 
135  private:
136   std::vector<executorch::aten::SizesType> sizes_;
137   std::vector<executorch::aten::StridesType> strides_;
138   std::vector<executorch::aten::DimOrderType> dim_order_;
139   std::function<void(void*)> deleter_ = nullptr;
140   void* data_ = nullptr;
141   executorch::aten::ScalarType type_ = executorch::aten::ScalarType::Float;
142   executorch::aten::TensorShapeDynamism dynamism_ =
143       executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND;
144 };
145 
146 /**
147  * Creates a TensorPtrMaker instance for building a TensorPtr from a raw data
148  * pointer and tensor sizes.
149  *
150  * The TensorPtrMaker returned by this function allows for further customization
151  * of the tensor's properties, such as data type, dimension order, strides, and
152  * shape dynamism, before finalizing the TensorPtr creation.
153  *
154  * @param data A pointer to the raw data to be used by the tensor. It must
155  * outlive the TensorPtr created by this function.
156  * @param sizes A vector specifying the size of each dimension.
157  * @param type The scalar type of the tensor elements.
158  * @return A TensorPtrMaker instance for creating a TensorPtr.
159  */
160 inline TensorPtrMaker for_blob(
161     void* data,
162     std::vector<executorch::aten::SizesType> sizes,
163     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float) {
164   return TensorPtrMaker(data, std::move(sizes), type);
165 }
166 
167 /**
168  * Creates a TensorPtr from a raw data pointer and tensor sizes, with an
169  * optional dynamism setting.
170  *
171  * This function provides a convenient way to create a tensor from existing
172  * data, with the option to specify whether the tensor's shape is static or
173  * dynamic.
174  *
175  * @param data A pointer to the raw data used by the tensor. The data must
176  * outlive the TensorPtr created by this function.
177  * @param sizes A vector specifying the size of each dimension.
178  * @param type The scalar type of the tensor elements.
179  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
180  * @return A TensorPtr instance managing the newly created Tensor.
181  */
182 inline TensorPtr from_blob(
183     void* data,
184     std::vector<executorch::aten::SizesType> sizes,
185     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
186     executorch::aten::TensorShapeDynamism dynamism =
187         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
188   return for_blob(data, std::move(sizes), type)
189       .dynamism(dynamism)
190       .make_tensor_ptr();
191 }
192 
193 /**
194  * Creates a TensorPtr from a raw data pointer, tensor sizes, and strides, with
195  * an optional dynamism setting.
196  *
197  * This function allows for the creation of a tensor from existing data, with
198  * the option to specify custom strides for each dimension and whether the
199  * tensor’s shape is static, dynamic, or bounded.
200  *
201  * @param data A pointer to the raw data used by the tensor. The data must
202  * outlive the TensorPtr created by this function.
203  * @param sizes A vector specifying the size of each dimension.
204  * @param strides A vector specifying the stride for each dimension.
205  * @param type The scalar type of the tensor elements.
206  * @param dynamism Specifies whether the tensor's shape is static, dynamic, or
207  * bounded.
208  * @return A TensorPtr instance managing the newly created Tensor.
209  */
210 inline TensorPtr from_blob(
211     void* data,
212     std::vector<executorch::aten::SizesType> sizes,
213     std::vector<executorch::aten::StridesType> strides,
214     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
215     executorch::aten::TensorShapeDynamism dynamism =
216         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
217   return for_blob(data, std::move(sizes), type)
218       .strides(std::move(strides))
219       .dynamism(dynamism)
220       .make_tensor_ptr();
221 }
222 
223 /**
224  * Creates a TensorPtr from a raw data pointer and tensor sizes, with an
225  * optional dynamism setting.
226  *
227  * This function is a convenient way to create a tensor from existing data, with
228  * the option to specify whether the tensor's shape is static, dynamic, or
229  * bounded.
230  *
231  * @param data A pointer to the raw data to be used by the tensor. It must
232  * outlive the TensorPtr created by this function.
233  * @param sizes A vector specifying the size of each dimension.
234  * @param type The scalar type of the tensor elements.
235  * @param deleter A function to delete the data when it's no longer needed.
236  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
237  * @return A TensorPtr instance that manages the newly created Tensor.
238  */
239 inline TensorPtr from_blob(
240     void* data,
241     std::vector<executorch::aten::SizesType> sizes,
242     executorch::aten::ScalarType type,
243     std::function<void(void*)>&& deleter,
244     executorch::aten::TensorShapeDynamism dynamism =
245         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
246   return for_blob(data, std::move(sizes), type)
247       .deleter(std::move(deleter))
248       .dynamism(dynamism)
249       .make_tensor_ptr();
250 }
251 
252 /**
253  * Creates a TensorPtr from a raw data pointer, tensor sizes, and strides, with
254  * an optional dynamism setting.
255  *
256  * This function allows for the creation of a tensor from existing data, with
257  * the option to specify custom strides for each dimension and whether the
258  * tensor's shape is static, dynamic, or bounded.
259  *
260  * @param data A pointer to the raw data to be used by the tensor. It must
261  * outlive the TensorPtr created by this function.
262  * @param sizes A vector specifying the size of each dimension.
263  * @param strides A vector specifying the stride for each dimension.
264  * @param type The scalar type of the tensor elements.
265  * @param deleter A function to delete the data when it's no longer needed.
266  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
267  * @return A TensorPtr instance that manages the newly created Tensor.
268  */
269 inline TensorPtr from_blob(
270     void* data,
271     std::vector<executorch::aten::SizesType> sizes,
272     std::vector<executorch::aten::StridesType> strides,
273     executorch::aten::ScalarType type,
274     std::function<void(void*)>&& deleter,
275     executorch::aten::TensorShapeDynamism dynamism =
276         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
277   return for_blob(data, std::move(sizes), type)
278       .strides(std::move(strides))
279       .deleter(std::move(deleter))
280       .dynamism(dynamism)
281       .make_tensor_ptr();
282 }
283 
284 /**
285  * Creates a TensorPtr with the specified sizes, strides, and properties.
286  *
287  * This function allocates memory for the tensor elements but does not
288  * initialize them with any specific values. The tensor is created with the
289  * specified strides.
290  *
291  * @param sizes A vector specifying the size of each dimension.
292  * @param strides A vector specifying the stride for each dimension.
293  * @param type The scalar type of the tensor elements.
294  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
295  * @return A TensorPtr instance managing the newly created Tensor.
296  */
297 TensorPtr empty_strided(
298     std::vector<executorch::aten::SizesType> sizes,
299     std::vector<executorch::aten::StridesType> strides,
300     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
301     executorch::aten::TensorShapeDynamism dynamism =
302         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND);
303 
304 /**
305  * Creates an empty TensorPtr with the same size and properties as the given
306  * tensor.
307  *
308  * This function allocates memory for the tensor elements but does not
309  * initialize them with any specific values.
310  *
311  * @param other A reference to another tensor, whose size and properties are
312  * used.
313  * @param type The scalar type of the tensor elements. If not provided, the
314  * scalar type of the other tensor is used.
315  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
316  * @return A TensorPtr instance managing the newly created Tensor.
317  */
318 inline TensorPtr empty_like(
319     const TensorPtr& other,
320     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
321     executorch::aten::TensorShapeDynamism dynamism =
322         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
323   if (type == executorch::aten::ScalarType::Undefined) {
324     type = other->scalar_type();
325   }
326   return empty_strided(
327       {other->sizes().begin(), other->sizes().end()},
328       {other->strides().begin(), other->strides().end()},
329       type,
330       dynamism);
331 }
332 
333 /**
334  * Creates an empty TensorPtr with the specified sizes and properties.
335  *
336  * This function allocates memory for the tensor elements but does not
337  * initialize them with any specific values.
338  *
339  * @param sizes A vector specifying the size of each dimension.
340  * @param type The scalar type of the tensor elements.
341  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
342  * @return A TensorPtr instance managing the newly created Tensor.
343  */
344 inline TensorPtr empty(
345     std::vector<executorch::aten::SizesType> sizes,
346     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
347     executorch::aten::TensorShapeDynamism dynamism =
348         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
349   return empty_strided(std::move(sizes), {}, type, dynamism);
350 }
351 
352 /**
353  * Creates a TensorPtr filled with the specified value.
354  *
355  * @param sizes A vector specifying the size of each dimension.
356  * @param strides A vector specifying the stride for each dimension.
357  * @param fill_value The value to fill the tensor with.
358  * @param type The scalar type of the tensor elements.
359  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
360  * @return A TensorPtr instance managing the newly created Tensor.
361  */
362 TensorPtr full_strided(
363     std::vector<executorch::aten::SizesType> sizes,
364     std::vector<executorch::aten::StridesType> strides,
365     executorch::aten::Scalar fill_value,
366     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
367     executorch::aten::TensorShapeDynamism dynamism =
368         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND);
369 
370 /**
371  * Creates a TensorPtr filled with the specified value, with the same size and
372  * properties as another tensor.
373  *
374  * @param other A reference to another tensor, whose size and properties will be
375  * used.
376  * @param fill_value The value to fill the tensor with.
377  * @param type The scalar type of the tensor elements. If not specified, the
378  * scalar type of the other tensor is used.
379  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
380  * @return A TensorPtr instance managing the newly created Tensor.
381  */
382 inline TensorPtr full_like(
383     const TensorPtr& other,
384     executorch::aten::Scalar fill_value,
385     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
386     executorch::aten::TensorShapeDynamism dynamism =
387         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
388   if (type == executorch::aten::ScalarType::Undefined) {
389     type = other->scalar_type();
390   }
391   return full_strided(
392       {other->sizes().begin(), other->sizes().end()},
393       {other->strides().begin(), other->strides().end()},
394       fill_value,
395       type,
396       dynamism);
397 }
398 
399 /**
400  * Creates a TensorPtr filled with the specified value.
401  *
402  * @param sizes A vector specifying the size of each dimension.
403  * @param fill_value The value used to fill the tensor.
404  * @param type The scalar type of the tensor elements.
405  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
406  * @return A TensorPtr instance managing the newly created Tensor.
407  */
408 inline TensorPtr full(
409     std::vector<executorch::aten::SizesType> sizes,
410     executorch::aten::Scalar fill_value,
411     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
412     executorch::aten::TensorShapeDynamism dynamism =
413         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
414   return full_strided(std::move(sizes), {}, fill_value, type, dynamism);
415 }
416 
417 /**
418  * Creates a TensorPtr holding a scalar value.
419  *
420  * @param value The scalar value for the tensor.
421  * @param type The scalar type of the tensor elements.
422  * @return A TensorPtr instance managing the newly created scalar Tensor.
423  */
424 inline TensorPtr scalar_tensor(
425     executorch::aten::Scalar value,
426     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float) {
427   return full({}, value, type);
428 }
429 
430 /**
431  * Creates a TensorPtr filled with ones, with the same size and properties as
432  * another tensor.
433  *
434  * @param other A reference to another tensor, whose size and properties are
435  * used.
436  * @param type The scalar type of the tensor elements. If not provided, the
437  * scalar type of the other tensor is used.
438  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
439  * @return A TensorPtr instance managing the newly created Tensor.
440  */
441 inline TensorPtr ones_like(
442     const TensorPtr& other,
443     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
444     executorch::aten::TensorShapeDynamism dynamism =
445         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
446   return full_like(other, 1, type, dynamism);
447 }
448 
449 /**
450  * Creates a TensorPtr filled with ones.
451  *
452  * @param sizes A vector specifying the size of each dimension.
453  * @param type The scalar type of the tensor elements.
454  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
455  * @return A TensorPtr instance managing the newly created Tensor.
456  */
457 inline TensorPtr ones(
458     std::vector<executorch::aten::SizesType> sizes,
459     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
460     executorch::aten::TensorShapeDynamism dynamism =
461         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
462   return full(std::move(sizes), 1, type, dynamism);
463 }
464 
465 /**
466  * Creates a TensorPtr filled with zeros, with the same size and properties as
467  * another tensor.
468  *
469  * @param other A reference to another tensor, whose size and properties will be
470  * used.
471  * @param type The scalar type of the tensor elements. If not specified, the
472  * scalar type of the `other` tensor is used.
473  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
474  * @return A TensorPtr instance managing the newly created Tensor.
475  */
476 inline TensorPtr zeros_like(
477     const TensorPtr& other,
478     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
479     executorch::aten::TensorShapeDynamism dynamism =
480         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
481   return full_like(other, 0, type, dynamism);
482 }
483 
484 /**
485  * Creates a TensorPtr filled with zeros.
486  *
487  * @param sizes A vector specifying the size of each dimension.
488  * @param type The scalar type of the tensor elements.
489  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
490  * @return A TensorPtr instance managing the newly created Tensor.
491  */
492 inline TensorPtr zeros(
493     std::vector<executorch::aten::SizesType> sizes,
494     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
495     executorch::aten::TensorShapeDynamism dynamism =
496         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
497   return full(std::move(sizes), 0, type, dynamism);
498 }
499 
500 /**
501  * Creates a TensorPtr filled with random values between 0 and 1.
502  *
503  * @param sizes A vector specifying the size of each dimension.
504  * @param strides A vector specifying the stride for each dimension.
505  * @param type The scalar type of the tensor elements.
506  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
507  * @return A TensorPtr instance managing the newly created Tensor.
508  **/
509 TensorPtr rand_strided(
510     std::vector<executorch::aten::SizesType> sizes,
511     std::vector<executorch::aten::StridesType> strides,
512     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
513     executorch::aten::TensorShapeDynamism dynamism =
514         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND);
515 
516 /**
517  * Creates a TensorPtr filled with random values between 0 and 1.
518  *
519  * @param other A reference to another tensor, whose size and properties will be
520  * used.
521  * @param type The scalar type of the tensor elements. If not specified, the
522  * scalar type of the other tensor is used.
523  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
524  * @return A TensorPtr instance managing the newly created Tensor.
525  */
526 inline TensorPtr rand_like(
527     const TensorPtr& other,
528     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
529     executorch::aten::TensorShapeDynamism dynamism =
530         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
531   if (type == executorch::aten::ScalarType::Undefined) {
532     type = other->scalar_type();
533   }
534   return rand_strided(
535       {other->sizes().begin(), other->sizes().end()},
536       {other->strides().begin(), other->strides().end()},
537       type,
538       dynamism);
539 }
540 
541 /**
542  * Creates a TensorPtr filled with random values between 0 and 1.
543  *
544  * @param sizes A vector specifying the size of each dimension.
545  * @param type The scalar type of the tensor elements.
546  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
547  * @return A TensorPtr instance managing the newly created Tensor.
548  */
549 inline TensorPtr rand(
550     std::vector<executorch::aten::SizesType> sizes,
551     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
552     executorch::aten::TensorShapeDynamism dynamism =
553         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
554   return rand_strided(std::move(sizes), {}, type, dynamism);
555 }
556 
557 /**
558  * Creates a TensorPtr filled with random values between 0 and 1, with specified
559  * strides.
560  *
561  * @param sizes A vector specifying the size of each dimension.
562  * @param strides A vector specifying the stride for each dimension.
563  * @param type The scalar type of the tensor elements.
564  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
565  * @return A TensorPtr instance managing the newly created Tensor.
566  */
567 TensorPtr randn_strided(
568     std::vector<executorch::aten::SizesType> sizes,
569     std::vector<executorch::aten::StridesType> strides,
570     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
571     executorch::aten::TensorShapeDynamism dynamism =
572         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND);
573 
574 /**
575  * Creates a TensorPtr filled with random values from a normal distribution.
576  *
577  * @param other A reference to another tensor, whose size and properties will be
578  * used.
579  * @param type The scalar type of the tensor elements. If not specified, the
580  * scalar type of the other tensor is used.
581  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
582  * @return A TensorPtr instance managing the newly created Tensor.
583  */
584 inline TensorPtr randn_like(
585     const TensorPtr& other,
586     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
587     executorch::aten::TensorShapeDynamism dynamism =
588         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
589   if (type == executorch::aten::ScalarType::Undefined) {
590     type = other->scalar_type();
591   }
592   return randn_strided(
593       {other->sizes().begin(), other->sizes().end()},
594       {other->strides().begin(), other->strides().end()},
595       type,
596       dynamism);
597 }
598 
599 /**
600  * Creates a TensorPtr filled with random values sampled from a normal
601  * distribution.
602  *
603  * @param sizes A vector specifying the size of each dimension.
604  * @param type The scalar type of the tensor elements.
605  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
606  * @return A TensorPtr instance managing the newly created Tensor.
607  */
608 inline TensorPtr randn(
609     std::vector<executorch::aten::SizesType> sizes,
610     executorch::aten::ScalarType type = executorch::aten::ScalarType::Float,
611     executorch::aten::TensorShapeDynamism dynamism =
612         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
613   return randn_strided(std::move(sizes), {}, type, dynamism);
614 }
615 
616 /**
617  * Creates a TensorPtr filled with random integer values in the given range.
618  *
619  * @param low The lower bound (inclusive) of the random values.
620  * @param high The upper bound (exclusive) of the random values.
621  * @param sizes A vector specifying the size of each dimension.
622  * @param strides A vector specifying the stride for each dimension.
623  * @param type The scalar type of the tensor elements.
624  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
625  * @return A TensorPtr instance managing the newly created Tensor.
626  */
627 TensorPtr randint_strided(
628     int64_t low,
629     int64_t high,
630     std::vector<executorch::aten::SizesType> sizes,
631     std::vector<executorch::aten::StridesType> strides,
632     executorch::aten::ScalarType type = executorch::aten::ScalarType::Int,
633     executorch::aten::TensorShapeDynamism dynamism =
634         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND);
635 
636 /**
637  * Creates a TensorPtr filled with random integer values in the given range.
638  *
639  * @param other A reference to another tensor, whose size and properties will be
640  * used.
641  * @param low The lower bound (inclusive) of the random values.
642  * @param high The upper bound (exclusive) of the random values.
643  * @param type The scalar type of the tensor elements. If not specified, the
644  * scalar type of the other tensor is used.
645  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
646  * @return A TensorPtr instance managing the newly created Tensor.
647  */
648 inline TensorPtr randint_like(
649     const TensorPtr& other,
650     int64_t low,
651     int64_t high,
652     executorch::aten::ScalarType type = executorch::aten::ScalarType::Undefined,
653     executorch::aten::TensorShapeDynamism dynamism =
654         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
655   if (type == executorch::aten::ScalarType::Undefined) {
656     type = other->scalar_type();
657   }
658   return randint_strided(
659       low,
660       high,
661       {other->sizes().begin(), other->sizes().end()},
662       {other->strides().begin(), other->strides().end()},
663       type,
664       dynamism);
665 }
666 
667 /**
668  * Creates a TensorPtr filled with random integer values within the specified
669  * range.
670  *
671  * @param low The inclusive lower bound of the random values.
672  * @param high The exclusive upper bound of the random values.
673  * @param sizes A vector specifying the size of each dimension.
674  * @param type The scalar type of the tensor elements.
675  * @param dynamism Specifies whether the tensor's shape is static or dynamic.
676  * @return A TensorPtr instance managing the newly created Tensor.
677  */
678 inline TensorPtr randint(
679     int64_t low,
680     int64_t high,
681     std::vector<executorch::aten::SizesType> sizes,
682     executorch::aten::ScalarType type = executorch::aten::ScalarType::Int,
683     executorch::aten::TensorShapeDynamism dynamism =
684         executorch::aten::TensorShapeDynamism::DYNAMIC_BOUND) {
685   return randint_strided(low, high, std::move(sizes), {}, type, dynamism);
686 }
687 
688 } // namespace extension
689 } // namespace executorch
690