Skip to content

Commit 4084644

Browse files
JacobSzwejbkafacebook-github-bot
authored andcommitted
Back out "Re-apply D101260086: Android unified error reporting"
Summary: Original commit changeset: afc9ba215caa Original Phabricator Diff: D102493794 Differential Revision: D102493838
1 parent f7010f9 commit 4084644

10 files changed

Lines changed: 120 additions & 276 deletions

File tree

extension/android/executorch_android/src/androidTest/java/org/pytorch/executorch/LlmModuleInstrumentationTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ class LlmModuleInstrumentationTest : LlmCallback {
5454
@Test
5555
@Throws(IOException::class, URISyntaxException::class)
5656
fun testGenerate() {
57-
llmModule.load()
57+
val loadResult = llmModule.load()
58+
// Check that the model can be load successfully
59+
assertEquals(OK.toLong(), loadResult.toLong())
5860

5961
llmModule.generate(TEST_PROMPT, SEQ_LEN, this@LlmModuleInstrumentationTest)
6062
assertEquals(results.size.toLong(), SEQ_LEN.toLong())
@@ -275,6 +277,7 @@ class LlmModuleInstrumentationTest : LlmCallback {
275277
private const val TEST_FILE_NAME = "/stories.pte"
276278
private const val TOKENIZER_FILE_NAME = "/tokenizer.bin"
277279
private const val TEST_PROMPT = "Hello"
280+
private const val OK = 0x00
278281
private const val SEQ_LEN = 32
279282
}
280283
}

extension/android/executorch_android/src/androidTest/java/org/pytorch/executorch/ModuleInstrumentationTest.kt

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ class ModuleInstrumentationTest {
6666
fun testModuleLoadMethodAndForward() {
6767
val module = Module.load(getTestFilePath(TEST_FILE_NAME))
6868

69-
module.loadMethod(FORWARD_METHOD)
69+
val loadMethod = module.loadMethod(FORWARD_METHOD)
70+
Assert.assertEquals(loadMethod.toLong(), OK.toLong())
7071

7172
val results = module.forward()
7273
Assert.assertTrue(results[0].isTensor)
@@ -95,22 +96,17 @@ class ModuleInstrumentationTest {
9596
fun testModuleLoadMethodNonExistantMethod() {
9697
val module = Module.load(getTestFilePath(TEST_FILE_NAME))
9798

98-
val exception =
99-
Assert.assertThrows(ExecutorchRuntimeException::class.java) {
100-
module.loadMethod(NONE_METHOD)
101-
}
102-
Assert.assertEquals(
103-
ExecutorchRuntimeException.INVALID_ARGUMENT,
104-
exception.getErrorCode(),
105-
)
99+
val loadMethod = module.loadMethod(NONE_METHOD)
100+
Assert.assertEquals(loadMethod.toLong(), INVALID_ARGUMENT.toLong())
106101
}
107102

108103
@Test(expected = RuntimeException::class)
109104
@Throws(IOException::class)
110105
fun testNonPteFile() {
111106
val module = Module.load(getTestFilePath(NON_PTE_FILE_NAME))
112107

113-
module.loadMethod(FORWARD_METHOD)
108+
val loadMethod = module.loadMethod(FORWARD_METHOD)
109+
Assert.assertEquals(loadMethod.toLong(), INVALID_ARGUMENT.toLong())
114110
}
115111

116112
@Test
@@ -120,19 +116,22 @@ class ModuleInstrumentationTest {
120116

121117
module.destroy()
122118

123-
Assert.assertThrows(IllegalStateException::class.java) { module.loadMethod(FORWARD_METHOD) }
119+
val loadMethod = module.loadMethod(FORWARD_METHOD)
120+
Assert.assertEquals(loadMethod.toLong(), INVALID_STATE.toLong())
124121
}
125122

126123
@Test
127124
@Throws(IOException::class)
128125
fun testForwardOnDestroyedModule() {
129126
val module = Module.load(getTestFilePath(TEST_FILE_NAME))
130127

131-
module.loadMethod(FORWARD_METHOD)
128+
val loadMethod = module.loadMethod(FORWARD_METHOD)
129+
Assert.assertEquals(loadMethod.toLong(), OK.toLong())
132130

133131
module.destroy()
134132

135-
Assert.assertThrows(IllegalStateException::class.java) { module.forward() }
133+
val results = module.forward()
134+
Assert.assertEquals(0, results.size.toLong())
136135
}
137136

138137
@Ignore(
@@ -176,5 +175,9 @@ class ModuleInstrumentationTest {
176175
private const val NON_PTE_FILE_NAME = "/test.txt"
177176
private const val FORWARD_METHOD = "forward"
178177
private const val NONE_METHOD = "none"
178+
private const val OK = 0x00
179+
private const val INVALID_STATE = 0x2
180+
private const val INVALID_ARGUMENT = 0x12
181+
private const val ACCESS_FAILED = 0x22
179182
}
180183
}

extension/android/executorch_android/src/main/java/org/pytorch/executorch/ExecutorchRuntimeException.java

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,83 +12,34 @@
1212
import java.util.HashMap;
1313
import java.util.Map;
1414

15-
/**
16-
* Base exception for all ExecuTorch runtime errors. Each instance carries an integer error code
17-
* corresponding to the native {@code runtime/core/error.h} values, accessible via {@link
18-
* #getErrorCode()}.
19-
*/
2015
public class ExecutorchRuntimeException extends RuntimeException {
2116
// Error code constants - keep in sync with runtime/core/error.h
22-
2317
// System errors
24-
25-
/** Operation completed successfully. */
2618
public static final int OK = 0x00;
27-
28-
/** An unexpected internal error occurred in the runtime. */
2919
public static final int INTERNAL = 0x01;
30-
31-
/** The runtime or method is in an invalid state for the requested operation. */
3220
public static final int INVALID_STATE = 0x02;
33-
34-
/** The method has finished execution and has no more work to do. */
3521
public static final int END_OF_METHOD = 0x03;
3622

37-
/** A required resource has already been loaded. */
38-
public static final int ALREADY_LOADED = 0x04;
39-
4023
// Logical errors
41-
42-
/** The requested operation is not supported by this build or backend. */
4324
public static final int NOT_SUPPORTED = 0x10;
44-
45-
/** The requested operation has not been implemented. */
4625
public static final int NOT_IMPLEMENTED = 0x11;
47-
48-
/** One or more arguments passed to the operation are invalid. */
4926
public static final int INVALID_ARGUMENT = 0x12;
50-
51-
/** A value or tensor has an unexpected type. */
5227
public static final int INVALID_TYPE = 0x13;
53-
54-
/** A required operator kernel is not registered. */
5528
public static final int OPERATOR_MISSING = 0x14;
56-
57-
/** The maximum number of registered kernels has been exceeded. */
5829
public static final int REGISTRATION_EXCEEDING_MAX_KERNELS = 0x15;
59-
60-
/** A kernel with the same name is already registered. */
6130
public static final int REGISTRATION_ALREADY_REGISTERED = 0x16;
6231

6332
// Resource errors
64-
65-
/** A required resource (file, tensor, program) was not found. */
6633
public static final int NOT_FOUND = 0x20;
67-
68-
/** A memory allocation failed. */
6934
public static final int MEMORY_ALLOCATION_FAILED = 0x21;
70-
71-
/** Access to a resource was denied or failed. */
7235
public static final int ACCESS_FAILED = 0x22;
73-
74-
/** The loaded program is malformed or incompatible. */
7536
public static final int INVALID_PROGRAM = 0x23;
76-
77-
/** External data referenced by the program is invalid or missing. */
7837
public static final int INVALID_EXTERNAL_DATA = 0x24;
79-
80-
/** The system has run out of a required resource. */
8138
public static final int OUT_OF_RESOURCES = 0x25;
8239

8340
// Delegate errors
84-
85-
/** A delegate reported an incompatible model or configuration. */
8641
public static final int DELEGATE_INVALID_COMPATIBILITY = 0x30;
87-
88-
/** A delegate failed to allocate required memory. */
8942
public static final int DELEGATE_MEMORY_ALLOCATION_FAILED = 0x31;
90-
91-
/** A delegate received an invalid or stale handle. */
9243
public static final int DELEGATE_INVALID_HANDLE = 0x32;
9344

9445
private static final Map<Integer, String> ERROR_CODE_MESSAGES;
@@ -101,7 +52,6 @@ public class ExecutorchRuntimeException extends RuntimeException {
10152
map.put(INTERNAL, "Internal error");
10253
map.put(INVALID_STATE, "Invalid state");
10354
map.put(END_OF_METHOD, "End of method reached");
104-
map.put(ALREADY_LOADED, "Already loaded");
10555
// Logical errors
10656
map.put(NOT_SUPPORTED, "Operation not supported");
10757
map.put(NOT_IMPLEMENTED, "Operation not implemented");
@@ -133,7 +83,7 @@ static String formatMessage(int errorCode, String details) {
13383

13484
String safeDetails = details != null ? details : "No details provided";
13585
return String.format(
136-
"[ExecuTorch Error 0x%s] %s: %s",
86+
"[Executorch Error 0x%s] %s: %s",
13787
Integer.toHexString(errorCode), baseMessage, safeDetails);
13888
}
13989

@@ -161,12 +111,10 @@ public ExecutorchRuntimeException(int errorCode, String details) {
161111
this.errorCode = errorCode;
162112
}
163113

164-
/** Returns the numeric error code from {@code runtime/core/error.h}. */
165114
public int getErrorCode() {
166115
return errorCode;
167116
}
168117

169-
/** Returns detailed log output captured from the native runtime, if available. */
170118
public String getDetailedError() {
171119
return ErrorHelper.getDetailedErrorLogs();
172120
}

extension/android/executorch_android/src/main/java/org/pytorch/executorch/Module.java

Lines changed: 22 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
package org.pytorch.executorch;
1010

11+
import android.util.Log;
1112
import com.facebook.jni.HybridData;
1213
import com.facebook.jni.annotations.DoNotStrip;
1314
import com.facebook.soloader.nativeloader.NativeLoader;
@@ -129,10 +130,11 @@ public EValue[] forward(EValue... inputs) {
129130
* @return return value from the method.
130131
*/
131132
public EValue[] execute(String methodName, EValue... inputs) {
132-
mLock.lock();
133133
try {
134+
mLock.lock();
134135
if (!mHybridData.isValid()) {
135-
throw new IllegalStateException("Module has been destroyed");
136+
Log.e("ExecuTorch", "Attempt to use a destroyed module");
137+
return new EValue[0];
136138
}
137139
return executeNative(methodName, inputs);
138140
} finally {
@@ -149,17 +151,17 @@ public EValue[] execute(String methodName, EValue... inputs) {
149151
* synchronous, and will block until the method is loaded. Therefore, it is recommended to call
150152
* this on a background thread. However, users need to make sure that they don't execute before
151153
* this function returns.
154+
*
155+
* @return the Error code if there was an error loading the method
152156
*/
153-
public void loadMethod(String methodName) {
154-
mLock.lock();
157+
public int loadMethod(String methodName) {
155158
try {
159+
mLock.lock();
156160
if (!mHybridData.isValid()) {
157-
throw new IllegalStateException("Module has been destroyed");
158-
}
159-
int errorCode = loadMethodNative(methodName);
160-
if (errorCode != 0) {
161-
throw new ExecutorchRuntimeException(errorCode, "Failed to load method: " + methodName);
161+
Log.e("ExecuTorch", "Attempt to use a destroyed module");
162+
return 0x2; // InvalidState
162163
}
164+
return loadMethodNative(methodName);
163165
} finally {
164166
mLock.unlock();
165167
}
@@ -182,20 +184,8 @@ public void loadMethod(String methodName) {
182184
*
183185
* @return name of methods in this Module
184186
*/
185-
public String[] getMethods() {
186-
mLock.lock();
187-
try {
188-
if (!mHybridData.isValid()) {
189-
throw new IllegalStateException("Module has been destroyed");
190-
}
191-
return getMethodsNative();
192-
} finally {
193-
mLock.unlock();
194-
}
195-
}
196-
197187
@DoNotStrip
198-
private native String[] getMethodsNative();
188+
public native String[] getMethods();
199189

200190
/**
201191
* Get the corresponding @MethodMetadata for a method
@@ -204,19 +194,11 @@ public String[] getMethods() {
204194
* @return @MethodMetadata for this method
205195
*/
206196
public MethodMetadata getMethodMetadata(String name) {
207-
mLock.lock();
208-
try {
209-
if (!mHybridData.isValid()) {
210-
throw new IllegalStateException("Module has been destroyed");
211-
}
212-
MethodMetadata methodMetadata = mMethodMetadata.get(name);
213-
if (methodMetadata == null) {
214-
throw new IllegalArgumentException("method " + name + " does not exist for this module");
215-
}
216-
return methodMetadata;
217-
} finally {
218-
mLock.unlock();
197+
MethodMetadata methodMetadata = mMethodMetadata.get(name);
198+
if (methodMetadata == null) {
199+
throw new IllegalArgumentException("method " + name + " does not exist for this module");
219200
}
201+
return methodMetadata;
220202
}
221203

222204
@DoNotStrip
@@ -228,15 +210,7 @@ public static String[] readLogBufferStatic() {
228210

229211
/** Retrieve the in-memory log buffer, containing the most recent ExecuTorch log entries. */
230212
public String[] readLogBuffer() {
231-
mLock.lock();
232-
try {
233-
if (!mHybridData.isValid()) {
234-
throw new IllegalStateException("Module has been destroyed");
235-
}
236-
return readLogBufferNative();
237-
} finally {
238-
mLock.unlock();
239-
}
213+
return readLogBufferNative();
240214
}
241215

242216
@DoNotStrip
@@ -250,20 +224,8 @@ public String[] readLogBuffer() {
250224
* @return true if the etdump was successfully written, false otherwise.
251225
*/
252226
@Experimental
253-
public boolean etdump() {
254-
mLock.lock();
255-
try {
256-
if (!mHybridData.isValid()) {
257-
throw new IllegalStateException("Module has been destroyed");
258-
}
259-
return etdumpNative();
260-
} finally {
261-
mLock.unlock();
262-
}
263-
}
264-
265227
@DoNotStrip
266-
private native boolean etdumpNative();
228+
public native boolean etdump();
267229

268230
/**
269231
* Explicitly destroys the native Module object. Calling this method is not required, as the
@@ -279,7 +241,10 @@ public void destroy() {
279241
mLock.unlock();
280242
}
281243
} else {
282-
throw new IllegalStateException("Cannot destroy module while method is executing");
244+
Log.w(
245+
"ExecuTorch",
246+
"Destroy was called while the module was in use. Resources will not be immediately"
247+
+ " released.");
283248
}
284249
}
285250
}

extension/android/executorch_android/src/main/java/org/pytorch/executorch/extension/llm/LlmCallback.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,5 @@ default void onStats(String stats) {}
4646
* @param message Human-readable error description
4747
*/
4848
@DoNotStrip
49-
default void onError(int errorCode, String message) {
50-
try {
51-
android.util.Log.e("ExecuTorch", "LLM error " + errorCode + ": " + message);
52-
} catch (Throwable t) {
53-
System.err.println("ExecuTorch LLM error " + errorCode + ": " + message);
54-
}
55-
}
49+
default void onError(int errorCode, String message) {}
5650
}

0 commit comments

Comments
 (0)