Skip to content

Commit fc844f6

Browse files
committed
Add Java runtime API and JNI layer
1 parent 33d4790 commit fc844f6

File tree

4 files changed

+116
-1
lines changed

4 files changed

+116
-1
lines changed

extension/android/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ set(executorch_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../lib/cmake/ExecuTorch)
6464
find_package(executorch CONFIG REQUIRED)
6565
target_link_options_shared_lib(executorch)
6666

67-
add_library(executorch_jni SHARED jni/jni_layer.cpp jni/log.cpp)
67+
add_library(executorch_jni SHARED jni/jni_layer.cpp jni/log.cpp jni/jni_layer_runtime.cpp)
6868

6969
set(link_libraries)
7070
list(
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
package org.pytorch.executorch;
10+
11+
import org.pytorch.executorch.annotations.Experimental;
12+
import com.facebook.jni.annotations.DoNotStrip;
13+
import com.facebook.soloader.nativeloader.NativeLoader;
14+
import com.facebook.soloader.nativeloader.SystemDelegate;
15+
16+
/**
17+
* Java API to access native runtime functionality on Android.
18+
*
19+
* <p>Warning: These APIs are experimental and subject to change without notice.
20+
*/
21+
@Experimental
22+
@DoNotStrip
23+
public class Runtime {
24+
private static boolean initialized = false;
25+
26+
static {
27+
if (!NativeLoader.isInitialized()) {
28+
NativeLoader.init(new SystemDelegate());
29+
}
30+
// Loads libexecutorch.so from jniLibs
31+
NativeLoader.loadLibrary("executorch");
32+
initialized = true;
33+
}
34+
35+
public static boolean isInitialized() {
36+
return initialized;
37+
}
38+
39+
@DoNotStrip
40+
public static native String[] getRegisteredOps();
41+
42+
@DoNotStrip
43+
public static native String[] getRegisteredBackends();
44+
}

extension/android/jni/jni_layer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,11 @@ extern void register_natives_for_llm();
491491
// No op if we don't build LLM
492492
void register_natives_for_llm() {}
493493
#endif
494+
extern void register_natives_for_runtime();
494495
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
495496
return facebook::jni::initialize(vm, [] {
496497
executorch::extension::ExecuTorchJni::registerNatives();
497498
register_natives_for_llm();
499+
register_natives_for_runtime();
498500
});
499501
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#include <jni.h>
10+
#include <fbjni/fbjni.h>
11+
12+
#include <executorch/runtime/kernel/operator_registry.h>
13+
#include <executorch/runtime/backend/interface.h>
14+
15+
namespace executorch_jni {
16+
namespace runtime = ::executorch::ET_RUNTIME_NAMESPACE;
17+
18+
class AndroidRuntimeJni : public facebook::jni::JavaClass<AndroidRuntimeJni> {
19+
public:
20+
constexpr static const char* kJavaDescriptor = "Lorg/pytorch/executorch/Runtime;";
21+
22+
static void registerNatives() {
23+
javaClassStatic()->registerNatives({
24+
makeNativeMethod("getRegisteredOps", AndroidRuntimeJni::getRegisteredOps),
25+
makeNativeMethod("getRegisteredBackends", AndroidRuntimeJni::getRegisteredBackends),
26+
});
27+
}
28+
29+
// Returns a string array of all registered ops
30+
static facebook::jni::local_ref<facebook::jni::JArrayClass<jstring>>
31+
getRegisteredOps(facebook::jni::alias_ref<jclass>) {
32+
auto kernels = runtime::get_registered_kernels();
33+
auto result = facebook::jni::JArrayClass<jstring>::newArray(kernels.size());
34+
35+
for (size_t i = 0; i < kernels.size(); ++i) {
36+
auto op = facebook::jni::make_jstring(kernels[i].name_);
37+
result->setElement(i, op.get());
38+
}
39+
40+
return result;
41+
}
42+
43+
// Returns a string array of all registered backends
44+
static facebook::jni::local_ref<facebook::jni::JArrayClass<jstring>>
45+
getRegisteredBackends(facebook::jni::alias_ref<jclass>) {
46+
int num_backends = runtime::get_num_registered_backends();
47+
auto result = facebook::jni::JArrayClass<jstring>::newArray(num_backends);
48+
49+
for (int i = 0; i < num_backends; ++i) {
50+
auto name_result = runtime::get_backend_name(i);
51+
const char* name = "";
52+
53+
if (name_result.ok()) {
54+
name = *name_result;
55+
}
56+
57+
auto backend_str = facebook::jni::make_jstring(name);
58+
result->setElement(i, backend_str.get());
59+
}
60+
61+
return result;
62+
}
63+
};
64+
65+
} // namespace executorch_jni
66+
67+
void register_natives_for_runtime() {
68+
executorch_jni::AndroidRuntimeJni::registerNatives();
69+
}

0 commit comments

Comments
 (0)