@@ -148,4 +148,77 @@ - (void)testMulModelExecution {
148
148
}
149
149
}
150
150
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
+
151
224
@end
0 commit comments