Skip to content

Init Value with a generic scalar. #11429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions extension/apple/ExecuTorch/Exported/ExecuTorchValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,17 @@ __attribute__((deprecated("This API is experimental.")))
+ (instancetype)valueWithDouble:(ExecuTorchDoubleValue)value
NS_SWIFT_NAME(init(_:));

/**
* Creates an instance encapsulating a scalar value.
*
* The value's tag will be set according to the type encoding of the ExecuTorchScalarValue.
*
* @param value An ExecuTorchScalarValue.
* @return A new ExecuTorchValue instance with the appropriate tag.
*/
+ (instancetype)valueWithScalar:(ExecuTorchScalarValue)value
NS_SWIFT_NAME(init(_:));

/**
* Returns a copy of the value.
*
Expand Down
42 changes: 36 additions & 6 deletions extension/apple/ExecuTorch/Exported/ExecuTorchValue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,25 @@

#import <executorch/runtime/platform/assert.h>

static inline ExecuTorchValueTag deduceValueTag(NSNumber *number) {
ET_CHECK(number);
auto type = [number objCType][0];
type = (type >= 'A' && type <= 'Z') ? type + ('a' - 'A') : type;
switch (type) {
case 'c': return ExecuTorchValueTagBoolean;
case 's':
case 'i':
case 'q':
case 'l': return ExecuTorchValueTagInteger;
case 'f':
case 'd': return ExecuTorchValueTagDouble;
default: {
ET_CHECK_MSG(false, "Unsupported type: %c", type);
return ExecuTorchValueTagNone;
}
}
}

@interface ExecuTorchValue ()

- (instancetype)initWithTag:(ExecuTorchValueTag)tag
Expand All @@ -24,28 +43,39 @@ @implementation ExecuTorchValue {

+ (instancetype)valueWithTensor:(ExecuTorchTensor *)value {
ET_CHECK(value);
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagTensor value:value];
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagTensor
value:value];
}

+ (instancetype)valueWithString:(ExecuTorchStringValue)value {
ET_CHECK(value);
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagString value:value];
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagString
value:value];
}

+ (instancetype)valueWithBoolean:(ExecuTorchBooleanValue)value {
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagBoolean value:@(value)];
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagBoolean
value:@(value)];
}

+ (instancetype)valueWithInteger:(ExecuTorchIntegerValue)value {
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagInteger value:@(value)];
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagInteger
value:@(value)];
}

+ (instancetype)valueWithDouble:(ExecuTorchDoubleValue)value {
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagDouble value:@(value)];
return [[ExecuTorchValue alloc] initWithTag:ExecuTorchValueTagDouble
value:@(value)];
}

+ (instancetype)valueWithScalar:(ExecuTorchScalarValue)value {
return [[ExecuTorchValue alloc] initWithTag:deduceValueTag(value)
value:value];
}

- (instancetype)init {
return [self initWithTag:ExecuTorchValueTagNone value:nil];
return [self initWithTag:ExecuTorchValueTagNone
value:nil];
}

- (instancetype)initWithTag:(ExecuTorchValueTag)tag
Expand Down
27 changes: 13 additions & 14 deletions extension/apple/ExecuTorch/Internal/ExecuTorchUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,22 @@
using namespace runtime;

ScalarType deduceType(NSNumber *number) {
ET_CHECK(number);
auto type = [number objCType][0];
type = (type >= 'A' && type <= 'Z') ? type + ('a' - 'A') : type;
if (type == 'c') {
return ScalarType::Byte;
} else if (type == 's') {
return ScalarType::Short;
} else if (type == 'i') {
return ScalarType::Int;
} else if (type == 'q' || type == 'l') {
return ScalarType::Long;
} else if (type == 'f') {
return ScalarType::Float;
} else if (type == 'd') {
return ScalarType::Double;
switch(type) {
case 'c': return ScalarType::Byte;
case 's': return ScalarType::Short;
case 'i': return ScalarType::Int;
case 'q':
case 'l': return ScalarType::Long;
case 'f': return ScalarType::Float;
case 'd': return ScalarType::Double;
default: {
ET_CHECK_MSG(false, "Unsupported type: %c", type);
return ScalarType::Undefined;
}
}
ET_CHECK_MSG(false, "Unsupported type: %c", type);
return ScalarType::Undefined;
}

} // namespace executorch::extension::utils
38 changes: 38 additions & 0 deletions extension/apple/ExecuTorch/__tests__/ValueTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,44 @@ class ValueTest: XCTestCase {
XCTAssertEqual(value.double, 3.14)
}

func testScalarBoolean() {
let value = Value(true as NSNumber)
XCTAssertTrue(value.isBoolean)
XCTAssertEqual(value.boolean, true)

let value2 = Value(false as NSNumber)
XCTAssertTrue(value2.isBoolean)
XCTAssertEqual(value2.boolean, false)
}

func testScalarInteger() {
let value = Value(42 as NSNumber)
XCTAssertTrue(value.isInteger)
XCTAssertEqual(value.integer, 42)

let value2 = Value(Int16(7) as NSNumber)
XCTAssertTrue(value2.isInteger)
XCTAssertEqual(value2.integer, 7)

let value3 = Value(Int32(13) as NSNumber)
XCTAssertTrue(value3.isInteger)
XCTAssertEqual(value3.integer, 13)

let value4 = Value(Int64(64) as NSNumber)
XCTAssertTrue(value4.isInteger)
XCTAssertEqual(value4.integer, 64)
}

func testScalarDouble() {
let value = Value(3.14 as NSNumber)
XCTAssertTrue(value.isDouble)
XCTAssertEqual(value.double, 3.14)

let value2 = Value(Float(6.28) as NSNumber)
XCTAssertTrue(value2.isFloat)
XCTAssertEqual(value2.float, 6.28)
}

func testIsEqual() {
let noneValue1 = Value()
let noneValue2 = Value()
Expand Down
Loading