Skip to content

Commit e912c65

Browse files
authored
Helpers to create empty tensors.
Differential Revision: D74020941 Pull Request resolved: #10621
1 parent 385d860 commit e912c65

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

extension/apple/ExecuTorch/Exported/ExecuTorchTensor.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,4 +670,82 @@ __attribute__((deprecated("This API is experimental.")))
670670

671671
@end
672672

673+
#pragma mark - Empty Category
674+
675+
@interface ExecuTorchTensor (Empty)
676+
677+
/**
678+
* Creates an empty tensor with the specified shape, strides, data type, and shape dynamism.
679+
*
680+
* @param shape An NSArray of NSNumber objects representing the desired shape.
681+
* @param strides An NSArray of NSNumber objects representing the desired strides.
682+
* @param dataType An ExecuTorchDataType value specifying the element type.
683+
* @param shapeDynamism An ExecuTorchShapeDynamism value specifying whether the shape is static or dynamic.
684+
* @return A new, empty ExecuTorchTensor instance.
685+
*/
686+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
687+
strides:(NSArray<NSNumber *> *)strides
688+
dataType:(ExecuTorchDataType)dataType
689+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism
690+
NS_SWIFT_NAME(empty(shape:strides:dataType:shapeDynamism:));
691+
692+
/**
693+
* Creates an empty tensor with the specified shape, data type, and shape dynamism.
694+
*
695+
* @param shape An NSArray of NSNumber objects representing the desired shape.
696+
* @param dataType An ExecuTorchDataType value specifying the element type.
697+
* @param shapeDynamism An ExecuTorchShapeDynamism value specifying whether the shape is static or dynamic.
698+
* @return A new, empty ExecuTorchTensor instance.
699+
*/
700+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
701+
dataType:(ExecuTorchDataType)dataType
702+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism
703+
NS_SWIFT_NAME(empty(shape:dataType:shapeDynamism:));
704+
705+
/**
706+
* Creates an empty tensor with the specified shape and data type, using dynamic bound shape.
707+
*
708+
* @param shape An NSArray of NSNumber objects representing the desired shape.
709+
* @param dataType An ExecuTorchDataType value specifying the element type.
710+
* @return A new, empty ExecuTorchTensor instance.
711+
*/
712+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
713+
dataType:(ExecuTorchDataType)dataType
714+
NS_SWIFT_NAME(empty(shape:dataType:));
715+
716+
/**
717+
* Creates an empty tensor similar to the given tensor, with the specified data type and shape dynamism.
718+
*
719+
* @param tensor An existing ExecuTorchTensor instance whose shape and strides are used.
720+
* @param dataType An ExecuTorchDataType value specifying the desired element type.
721+
* @param shapeDynamism An ExecuTorchShapeDynamism value specifying whether the shape is static or dynamic.
722+
* @return A new, empty ExecuTorchTensor instance with the same shape as the provided tensor.
723+
*/
724+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor
725+
dataType:(ExecuTorchDataType)dataType
726+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism
727+
NS_SWIFT_NAME(empty(like:dataType:shapeDynamism:));
728+
729+
/**
730+
* Creates an empty tensor similar to the given tensor, with the specified data type.
731+
*
732+
* @param tensor An existing ExecuTorchTensor instance whose shape and strides are used.
733+
* @param dataType An ExecuTorchDataType value specifying the desired element type.
734+
* @return A new, empty ExecuTorchTensor instance with the same shape as the provided tensor.
735+
*/
736+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor
737+
dataType:(ExecuTorchDataType)dataType
738+
NS_SWIFT_NAME(empty(like:dataType:));
739+
740+
/**
741+
* Creates an empty tensor similar to the given tensor.
742+
*
743+
* @param tensor An existing ExecuTorchTensor instance.
744+
* @return A new, empty ExecuTorchTensor instance with the same properties as the provided tensor.
745+
*/
746+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor
747+
NS_SWIFT_NAME(empty(like:));
748+
749+
@end
750+
673751
NS_ASSUME_NONNULL_END

extension/apple/ExecuTorch/Exported/ExecuTorchTensor.mm

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,3 +591,61 @@ - (instancetype)initWithUnsignedInteger:(NSUInteger)scalar {
591591
}
592592

593593
@end
594+
595+
@implementation ExecuTorchTensor (Empty)
596+
597+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
598+
strides:(NSArray<NSNumber *> *)strides
599+
dataType:(ExecuTorchDataType)dataType
600+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism {
601+
auto tensor = empty_strided(
602+
utils::toVector<SizesType>(shape),
603+
utils::toVector<StridesType>(strides),
604+
static_cast<ScalarType>(dataType),
605+
static_cast<TensorShapeDynamism>(shapeDynamism)
606+
);
607+
return [[self alloc] initWithNativeInstance:&tensor];
608+
}
609+
610+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
611+
dataType:(ExecuTorchDataType)dataType
612+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism {
613+
return [self emptyTensorWithShape:shape
614+
strides:@[]
615+
dataType:dataType
616+
shapeDynamism:shapeDynamism];
617+
}
618+
619+
+ (instancetype)emptyTensorWithShape:(NSArray<NSNumber *> *)shape
620+
dataType:(ExecuTorchDataType)dataType {
621+
return [self emptyTensorWithShape:shape
622+
strides:@[]
623+
dataType:dataType
624+
shapeDynamism:ExecuTorchShapeDynamismDynamicBound];
625+
}
626+
627+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor
628+
dataType:(ExecuTorchDataType)dataType
629+
shapeDynamism:(ExecuTorchShapeDynamism)shapeDynamism {
630+
return [self emptyTensorWithShape:tensor.shape
631+
strides:tensor.strides
632+
dataType:dataType
633+
shapeDynamism:shapeDynamism];
634+
}
635+
636+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor
637+
dataType:(ExecuTorchDataType)dataType {
638+
return [self emptyTensorWithShape:tensor.shape
639+
strides:tensor.strides
640+
dataType:dataType
641+
shapeDynamism:tensor.shapeDynamism];
642+
}
643+
644+
+ (instancetype)emptyTensorLikeTensor:(ExecuTorchTensor *)tensor {
645+
return [self emptyTensorWithShape:tensor.shape
646+
strides:tensor.strides
647+
dataType:tensor.dataType
648+
shapeDynamism:tensor.shapeDynamism];
649+
}
650+
651+
@end

extension/apple/ExecuTorch/__tests__/TensorTest.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,4 +548,24 @@ class TensorTest: XCTestCase {
548548
XCTAssertEqual(UnsafeBufferPointer(start: pointer.assumingMemoryBound(to: UInt.self), count: count).first, 42)
549549
}
550550
}
551+
552+
func testEmpty() {
553+
let tensor = Tensor.empty(shape: [3, 4], dataType: .float)
554+
XCTAssertEqual(tensor.shape, [3, 4])
555+
XCTAssertEqual(tensor.count, 12)
556+
tensor.bytes { pointer, count, dataType in
557+
XCTAssertNotNil(pointer)
558+
XCTAssertEqual(count, 12)
559+
XCTAssertEqual(dataType, .float)
560+
}
561+
}
562+
563+
func testEmptyLike() {
564+
let other = Tensor.empty(shape: [2, 2], dataType: .int)
565+
let tensor = Tensor.empty(like: other)
566+
XCTAssertEqual(tensor.shape, other.shape)
567+
XCTAssertEqual(tensor.strides, other.strides)
568+
XCTAssertEqual(tensor.dimensionOrder, other.dimensionOrder)
569+
XCTAssertEqual(tensor.dataType, other.dataType)
570+
}
551571
}

0 commit comments

Comments
 (0)