diff --git a/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.h b/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.h index cdadaf2..c304e40 100644 --- a/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.h +++ b/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.h @@ -31,8 +31,6 @@ - (void)restartSession; - (void)restartSessionWithId:(NSString*)sessionId; -void freeCTensor(CTensor* tensor); - @end #endif diff --git a/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.m b/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.m index 1371079..7ca6866 100644 --- a/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.m +++ b/sdks/ios/deliteAI/Classes/sources/impl/controller/NimbleNetController.m @@ -376,79 +376,37 @@ - (NSDictionary*)run_task_controller:(NSString*)taskName modelInputsWithShape:(NSDictionary*)modelInputsWithShape { void* json_alloc = create_json_allocator(); - CTensors req; - req.numTensors = (int)modelInputsWithShape.count; - req.tensors = (CTensor*)malloc((req.numTensors) * sizeof(CTensor)); - - // model input transformer - - NSArray* keys = modelInputsWithShape.allKeys; - for (NSUInteger index = 0; index < keys.count; index++) { - NSString* inputName = keys[index]; - NSDictionary* modelInputObjectData = modelInputsWithShape[inputName]; - void* voidCastedData; - int inputDataType; - int64_t* int64ShapeArray = NULL; - int shapeArrayLength = 0; - if (modelInputObjectData[@"shape"] != [NSNull null]) { - NSArray* modelInputObjectShape = modelInputObjectData[@"shape"]; - shapeArrayLength = (int)modelInputObjectShape.count; - int64ShapeArray = (int64_t*)malloc(sizeof(int64_t) * shapeArrayLength); - for (NSUInteger i = 0; i < shapeArrayLength; i++) { - int64ShapeArray[i] = [(NSNumber*)modelInputObjectShape[i] longLongValue]; - } - - NSArray* arrayData = modelInputObjectData[@"data"]; - inputDataType = [modelInputObjectData[@"type"] intValue]; - NSUInteger arrayLength = [arrayData count]; - voidCastedData = convertArraytoVoidPointerWithJsonAlloc(arrayData, arrayLength, - inputDataType, json_alloc); - } else { - id data = modelInputObjectData[@"data"]; - inputDataType = [modelInputObjectData[@"type"] intValue]; - voidCastedData = convertSingularInputtoVoidPointer(data, inputDataType, json_alloc); - } - - if (voidCastedData == nil) { - freeCTensors(&req, index); - if (int64ShapeArray != NULL) { - free(int64ShapeArray); - int64ShapeArray = NULL; - } - deallocate_json_allocator(json_alloc); - return populateErrorReturnObject(5000, @"Datatype not yet supported"); - } - - req.tensors[index].name = strdup([inputName UTF8String]); - req.tensors[index].data = voidCastedData; - req.tensors[index].dataType = inputDataType; - req.tensors[index].shape = int64ShapeArray; - req.tensors[index].shapeLength = shapeArrayLength; + CTensors inCTensors; + NSDictionary* inCTensorsInitStatus = + cTensorsInitWithDict(&inCTensors, modelInputsWithShape, json_alloc); + if (inCTensorsInitStatus != nil) { + deallocate_json_allocator(json_alloc); + return inCTensorsInitStatus; } - CFTimeInterval startTime = CACurrentMediaTime(); - CTensors ret; - NimbleNetStatus* nimbleNetStatus = run_method([taskName UTF8String], req, &ret); + const CFTimeInterval startTime = CACurrentMediaTime(); + CTensors outCTensors; + NimbleNetStatus* nimbleNetStatus = run_method(taskName.UTF8String, inCTensors, &outCTensors); if (nimbleNetStatus == NULL) { - CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime; - long long int elapsedTimeinMicro = (long long int)(elapsedTime * 1000000); + const CFTimeInterval elapsedTime = CACurrentMediaTime() - startTime; + const long long int elapsedTimeinMicro = (long long int)(elapsedTime * 1000000); write_run_method_metric(taskName.UTF8String, elapsedTimeinMicro); } + cTensorsDelete(&inCTensors, inCTensors.numTensors); + bool status = false; if (nimbleNetStatus == NULL) { status = true; } - NSDictionary* output = convertCTensorsToNSDictionary(nimbleNetStatus, ret, json_alloc); - - freeCTensors(&req, req.numTensors); + NSDictionary* output = convertCTensorsToNSDictionary(nimbleNetStatus, outCTensors, json_alloc); if (nimbleNetStatus != NULL) { deallocate_nimblenet_status(nimbleNetStatus); } else { - deallocate_output_memory2(&ret); + deallocate_output_memory2(&outCTensors); } deallocate_json_allocator(json_alloc); @@ -461,26 +419,6 @@ - (void)reset_app_state_controller { } // private functions -void freeCTensor(CTensor* tensor) { - if (tensor->dataType != JSON && tensor->dataType != JSON_ARRAY) { - const bool freed = c_tensor_delete_data(tensor); - if (!freed) { - free(tensor->data); - } - } - if (tensor->shape != NULL) { - free(tensor->shape); - } - free(tensor->name); -} - -void freeCTensors(CTensors* req, NSUInteger index) { - for (int i = 0; i < index; i++) { - freeCTensor(&req->tensors[i]); - } - free(req->tensors); -} - NSString* getNimbleSdkDirectoryPath(void) { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); diff --git a/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.h b/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.h index 9f71cc4..64eeffd 100644 --- a/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.h +++ b/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.h @@ -9,12 +9,19 @@ #import "executor_structs.h" #import "nimble_net/c_tensor.h" +NSDictionary* cTensorsInitWithDict(CTensors* self_, NSDictionary* tensorsDict, void* json_alloc); + +void cTensorDelete(CTensor* self_); +void cTensorsDelete(CTensors* self_, NSUInteger index); + +// ================================================================================================= + @interface InputConverter : NSObject NimbleNetStatus* convertSingularInputToCTensor(id data, CTensor* child); void* convertSingularInputtoVoidPointer(id data, int dataType, void* json_alloc); -void* convertArraytoVoidPointerWithJsonAlloc(NSArray* arrayData, int arrayLength, int dataType, - void* json_alloc); -void* convertArraytoVoidPointer(NSArray* arrayData, int arrayLength, int dataType); +void* convertArraytoVoidPointerWithJsonAlloc(NSArray* arrayData, NSUInteger arrayLength, + int dataType, void* json_alloc); +void* convertArraytoVoidPointer(NSArray* arrayData, NSUInteger arrayLength, int dataType); @end diff --git a/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.m b/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.m index 327cbc1..f07c509 100644 --- a/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.m +++ b/sdks/ios/deliteAI/Classes/sources/impl/controller/converter/InputConverter.m @@ -8,14 +8,87 @@ #import #import +#import +#import #import "executor_structs.h" #import "nimblejson.hpp" +NSDictionary* cTensorsInitWithDict(CTensors* self_, NSDictionary* tensorsDict, void* json_alloc) { + self_->tensors = (CTensor*)malloc(sizeof(CTensor) * tensorsDict.count); + self_->numTensors = (int)tensorsDict.count; + + NSArray* keys = tensorsDict.allKeys; + for (NSUInteger index = 0; index < keys.count; index++) { + NSString* tensorName = keys[index]; + NSDictionary* tensorDict = tensorsDict[tensorName]; + + void* tensorData; + int tensorDataType = [tensorDict[@"type"] intValue]; + int64_t* tensorShape = NULL; + int tensorShapeLength = 0; + + if (tensorDict[@"shape"] != [NSNull null]) { + NSArray* tensorShapeArray = tensorDict[@"shape"]; + tensorShape = (int64_t*)malloc(sizeof(int64_t) * tensorShapeArray.count); + for (NSUInteger i = 0; i < tensorShapeArray.count; i++) { + tensorShape[i] = [(NSNumber*)tensorShapeArray[i] longLongValue]; + } + tensorShapeLength = (int)tensorShapeArray.count; + + NSArray* arrayData = tensorDict[@"data"]; + tensorData = convertArraytoVoidPointerWithJsonAlloc(arrayData, arrayData.count, + tensorDataType, json_alloc); + } else { + id data = tensorDict[@"data"]; + tensorData = convertSingularInputtoVoidPointer(data, tensorDataType, json_alloc); + } + + if (tensorData == NULL) { + cTensorsDelete(self_, index); + if (tensorShape != NULL) { + free(tensorShape); + tensorShape = NULL; + } + return populateErrorReturnObject(5000, @"Datatype not yet supported"); + } + + self_->tensors[index].name = strdup(tensorName.UTF8String); + self_->tensors[index].data = tensorData; + self_->tensors[index].dataType = tensorDataType; + self_->tensors[index].shape = tensorShape; + self_->tensors[index].shapeLength = tensorShapeLength; + } + + return nil; +} + +void cTensorDelete(CTensor* self_) { + free(self_->name); + if (self_->dataType != JSON && self_->dataType != JSON_ARRAY) { + const bool freed = c_tensor_delete_data(self_); + if (!freed) { + free(self_->data); + } + } + if (self_->shape != NULL) { + free(self_->shape); + } +} + +void cTensorsDelete(CTensors* self_, NSUInteger index) { + for (int i = 0; i < index; i++) { + cTensorDelete(&self_->tensors[i]); + } + free(self_->tensors); +} + +// ================================================================================================= + @implementation InputConverter : NSObject -void* convertArraytoVoidPointerWithJsonAlloc(NSArray* arrayData, int arrayLength, int dataType, - void* json_alloc) { +void* convertArraytoVoidPointerWithJsonAlloc(NSArray* arrayData, NSUInteger arrayLength, + int dataType, void* json_alloc) { switch (dataType) { case JSON_ARRAY: { return convertJsonArrayToVoidPointer(arrayData, json_alloc); @@ -25,7 +98,7 @@ @implementation InputConverter : NSObject } } -void* convertArraytoVoidPointer(NSArray* arrayData, int arrayLength, int dataType) { +void* convertArraytoVoidPointer(NSArray* arrayData, NSUInteger arrayLength, int dataType) { switch (dataType) { case STRING: { char** cArray = (char**)malloc(arrayLength * sizeof(char*)); diff --git a/sdks/ios/deliteAI/Classes/sources/impl/controller/interactor/FunctionPointersImpl.m b/sdks/ios/deliteAI/Classes/sources/impl/controller/interactor/FunctionPointersImpl.m index e53850a..fa8528e 100644 --- a/sdks/ios/deliteAI/Classes/sources/impl/controller/interactor/FunctionPointersImpl.m +++ b/sdks/ios/deliteAI/Classes/sources/impl/controller/interactor/FunctionPointersImpl.m @@ -252,7 +252,7 @@ void deallocate_ios_nimblenet_status(NimbleNetStatus* status){ void deallocate_frontend_ctensor(CTensor* ctensor){ if (ctensor == NULL) return; - freeCTensor(ctensor); + cTensorDelete(ctensor); } NimbleNetStatus* get_ios_object_size(IosObject proto, int* val) {