[Objective-C API] Add ORTSession methods to get input, overridable initializer, and output names. (#7837)

This commit is contained in:
Edward Chen 2021-05-26 19:54:55 -07:00 committed by GitHub
parent 94bb09bf47
commit fa093d8e45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 117 additions and 1 deletions

View file

@ -507,7 +507,8 @@ struct OrtApi {
_Outptr_ OrtTypeInfo** type_info);
/**
* \param value is set to a null terminated string allocated using 'allocator'. The caller is responsible for freeing it.
* \param value is set to a null terminated UTF-8 encoded string allocated using 'allocator'.
* The caller is responsible for freeing it.
*/
ORT_API2_STATUS(SessionGetInputName, _In_ const OrtSession* sess, size_t index, _Inout_ OrtAllocator* allocator,
_Outptr_ char** value);

View file

@ -64,6 +64,30 @@ NS_ASSUME_NONNULL_BEGIN
runOptions:(nullable ORTRunOptions*)runOptions
error:(NSError**)error;
/**
* Gets the model's input names.
*
* @param[out] error Optional error information set if an error occurs.
* @return An array of input names, or nil if an error occurs.
*/
- (nullable NSArray<NSString*>*)inputNamesWithError:(NSError**)error;
/**
* Gets the model's overridable initializer names.
*
* @param[out] error Optional error information set if an error occurs.
* @return An array of overridable initializer names, or nil if an error occurs.
*/
- (nullable NSArray<NSString*>*)overridableInitializerNamesWithError:(NSError**)error;
/**
* Gets the model's output names.
*
* @param[out] error Optional error information set if an error occurs.
* @return An array of output names, or nil if an error occurs.
*/
- (nullable NSArray<NSString*>*)outputNamesWithError:(NSError**)error;
@end
/**

View file

@ -13,12 +13,22 @@
#import "src/ort_env_internal.h"
#import "src/ort_value_internal.h"
namespace {
enum class NamedValueType {
Input,
OverridableInitializer,
Output,
};
} // namespace
NS_ASSUME_NONNULL_BEGIN
@implementation ORTSession {
std::optional<Ort::Session> _session;
}
#pragma mark - Public
- (nullable instancetype)initWithEnv:(ORTEnv*)env
modelPath:(NSString*)path
sessionOptions:(nullable ORTSessionOptions*)sessionOptions
@ -130,6 +140,62 @@ NS_ASSUME_NONNULL_BEGIN
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
- (nullable NSArray<NSString*>*)inputNamesWithError:(NSError**)error {
return [self namesWithType:NamedValueType::Input error:error];
}
- (nullable NSArray<NSString*>*)overridableInitializerNamesWithError:(NSError**)error {
return [self namesWithType:NamedValueType::OverridableInitializer error:error];
}
- (nullable NSArray<NSString*>*)outputNamesWithError:(NSError**)error {
return [self namesWithType:NamedValueType::Output error:error];
}
#pragma mark - Private
- (nullable NSArray<NSString*>*)namesWithType:(NamedValueType)namedValueType
error:(NSError**)error {
try {
auto getCount = [&session = *_session, namedValueType]() {
if (namedValueType == NamedValueType::Input) {
return session.GetInputCount();
} else if (namedValueType == NamedValueType::OverridableInitializer) {
return session.GetOverridableInitializerCount();
} else {
return session.GetOutputCount();
}
};
auto getName = [&session = *_session, namedValueType](size_t i, OrtAllocator* allocator) {
if (namedValueType == NamedValueType::Input) {
return session.GetInputName(i, allocator);
} else if (namedValueType == NamedValueType::OverridableInitializer) {
return session.GetOverridableInitializerName(i, allocator);
} else {
return session.GetOutputName(i, allocator);
}
};
const size_t nameCount = getCount();
Ort::AllocatorWithDefaultOptions allocator;
auto deleter = [ortAllocator = static_cast<OrtAllocator*>(allocator)](void* p) {
ortAllocator->Free(ortAllocator, p);
};
NSMutableArray<NSString*>* result = [NSMutableArray arrayWithCapacity:nameCount];
for (size_t i = 0; i < nameCount; ++i) {
auto name = std::unique_ptr<char[], decltype(deleter)>{getName(i, allocator), deleter};
[result addObject:[NSString stringWithUTF8String:name.get()]];
}
return result;
}
ORT_OBJC_API_IMPL_CATCH_RETURNING_NULLABLE(error)
}
@end
@implementation ORTSessionOptions {

View file

@ -147,6 +147,31 @@ NS_ASSUME_NONNULL_BEGIN
XCTAssertEqual(cActual, cExpected);
}
- (void)testGetNamesOk {
NSError* err = nil;
ORTSession* session = [[ORTSession alloc] initWithEnv:self.ortEnv
modelPath:[ORTSessionTest getAddModelPath]
sessionOptions:[ORTSessionTest makeSessionOptions]
error:&err];
XCTAssertNotNil(session);
XCTAssertNil(err);
NSArray<NSString*>* inputNames = [session inputNamesWithError:&err];
XCTAssertNotNil(inputNames);
XCTAssertNil(err);
XCTAssertEqualObjects(inputNames, (@[ @"A", @"B" ]));
NSArray<NSString*>* overridableInitializerNames = [session overridableInitializerNamesWithError:&err];
XCTAssertNotNil(overridableInitializerNames);
XCTAssertNil(err);
XCTAssertEqualObjects(overridableInitializerNames, (@[]));
NSArray<NSString*>* outputNames = [session outputNamesWithError:&err];
XCTAssertNotNil(outputNames);
XCTAssertNil(err);
XCTAssertEqualObjects(outputNames, (@[ @"C" ]));
}
- (void)testInitFailsWithInvalidPath {
NSString* invalidModelPath = [ORTSessionTest getTestDataWithRelativePath:@"/invalid/path/to/model.onnx"];
NSError* err = nil;