@@ -148,4 +148,77 @@ - (void)testMulModelExecution {
148148 }
149149}
150150
151+ // See https://github.com/pytorch/executorch/pull/10465
152+ - (void )testAutoreleasepoolError {
153+ NSURL *modelURL = [self .class bundledResourceWithName: @" add_coreml_all" extension: @" bin" ];
154+ NSError *localError = nil ;
155+ XCTAssertNotNil (modelURL);
156+
157+ NSData *modelData = [NSData dataWithContentsOfURL: modelURL];
158+ MLModelConfiguration *configuration = [[MLModelConfiguration alloc ] init ];
159+ configuration.computeUnits = MLComputeUnitsAll;
160+ ModelHandle *modelHandle = [self .modelManager loadModelFromAOTData: modelData
161+ configuration: configuration
162+ error: &localError];
163+ XCTAssert (modelHandle);
164+
165+ ETCoreMLModel *model = [self .modelManager modelWithHandle: modelHandle];
166+ XCTAssert (model);
167+
168+ NSArray <MLMultiArray *> *inputArrays =
169+ [ETCoreMLTestUtils inputsForModel: model repeatedValues: @[@(2 ), @(3 )] error: &localError];
170+ XCTAssert (inputArrays);
171+
172+ std::vector<MultiArray> multiArrays;
173+ multiArrays.reserve (inputArrays.count + model.orderedOutputNames .count );
174+ for (MLMultiArray *array in inputArrays) {
175+ auto dataTypeOpt = to_multiarray_data_type (array.dataType );
176+ XCTAssert (dataTypeOpt.has_value ());
177+ auto dataType = dataTypeOpt.value ();
178+
179+ std::vector<size_t > dims;
180+ for (NSNumber *n in array.shape ) {
181+ dims.push_back (n.unsignedLongValue );
182+ }
183+
184+ std::vector<ssize_t > strides (dims.size ());
185+ ssize_t currentStride = 1 ;
186+ for (NSInteger i = dims.size () - 1 ; i >= 0 ; --i) {
187+ strides[i] = currentStride;
188+ currentStride *= dims[i];
189+ }
190+
191+ multiArrays.emplace_back (array.dataPointer ,
192+ MultiArray::MemoryLayout (dataType, dims, strides));
193+ }
194+
195+ auto inputLayout = multiArrays[0 ].layout ();
196+ size_t bufferSize = inputLayout.num_bytes ();
197+ for (NSUInteger i = 0 ; i < model.orderedOutputNames .count ; ++i) {
198+ multiArrays.emplace_back (calloc (1 , bufferSize), inputLayout);
199+ }
200+ // corrupt first input shape to force error
201+ {
202+ auto originalLayout = multiArrays[0 ].layout ();
203+ auto corruptedDims = originalLayout.shape ();
204+ corruptedDims[0 ] += 1 ;
205+ multiArrays[0 ] = MultiArray (multiArrays[0 ].data (),
206+ MultiArray::MemoryLayout (originalLayout.dataType (),
207+ corruptedDims,
208+ originalLayout.strides ()));
209+ }
210+
211+ BOOL success = [self .modelManager executeModelWithHandle: modelHandle
212+ argsVec: multiArrays
213+ loggingOptions: ModelLoggingOptions ()
214+ eventLogger: nullptr
215+ error: &localError];
216+ XCTAssertFalse (success);
217+ XCTAssertNotNil (localError);
218+
219+ for (size_t i = inputArrays.count ; i < multiArrays.size (); ++i) {
220+ free (multiArrays[i].data ());
221+ }
222+ }
223+
151224@end
0 commit comments