1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 /*!
20 * \file org_apache_tvm_native_c_api.cc
21 * \brief tvm4j jni source file
22 */
23 #include "org_apache_tvm_native_c_api.h" // generated by javah
24 #ifdef TVM4J_ANDROID
25 #include "tvm_runtime.h"
26 #else
27 #include <dlfcn.h>
28 #include <dmlc/logging.h>
29 #include <dmlc/thread_local.h>
30 #include <tvm/runtime/c_runtime_api.h>
31 #endif
32 #include <iostream>
33 #include <cstring>
34 #include <vector>
35 #include <thread>
36
37 #include "jni_helper_func.h"
38
39 JavaVM *_jvm;
40 void *_tvmHandle = nullptr;
41 struct TVMFuncArgsThreadLocalEntry {
42 std::vector<TVMValue> tvmFuncArgValues;
43 std::vector<int> tvmFuncArgTypes;
44 // for later release
45 std::vector<std::pair<jstring, const char *> > tvmFuncArgPushedStrs;
46 std::vector<std::pair<jbyteArray, TVMByteArray *> > tvmFuncArgPushedBytes;
47 };
48 typedef dmlc::ThreadLocalStore<TVMFuncArgsThreadLocalEntry> TVMFuncArgsThreadLocalStore;
49
Java_org_apache_tvm_LibInfo_nativeLibInit(JNIEnv * env,jobject obj,jstring jtvmLibFile)50 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_nativeLibInit
51 (JNIEnv *env, jobject obj, jstring jtvmLibFile) {
52 if (_tvmHandle == NULL && !env->IsSameObject(jtvmLibFile, NULL)) {
53 const char *tvmLibFile = env->GetStringUTFChars(jtvmLibFile, 0);
54 _tvmHandle = dlopen(tvmLibFile, RTLD_LAZY | RTLD_GLOBAL);
55 env->ReleaseStringUTFChars(jtvmLibFile, tvmLibFile);
56 if (!_tvmHandle) {
57 fprintf(stderr, "%s\n", dlerror());
58 return 1;
59 }
60 }
61 return env->GetJavaVM(&_jvm);
62 }
63
Java_org_apache_tvm_LibInfo_shutdown(JNIEnv * env,jobject obj)64 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_shutdown(JNIEnv *env, jobject obj) {
65 if (_tvmHandle) {
66 dlclose(_tvmHandle);
67 }
68 return 0;
69 }
70
Java_org_apache_tvm_LibInfo_tvmGetLastError(JNIEnv * env,jobject obj)71 JNIEXPORT jstring JNICALL Java_org_apache_tvm_LibInfo_tvmGetLastError(JNIEnv * env, jobject obj) {
72 return env->NewStringUTF(TVMGetLastError());
73 }
74
75 // Function
Java_org_apache_tvm_LibInfo_tvmFuncPushArgLong(JNIEnv * env,jobject obj,jlong arg)76 JNIEXPORT void JNICALL Java_org_apache_tvm_LibInfo_tvmFuncPushArgLong(
77 JNIEnv *env, jobject obj, jlong arg) {
78 TVMValue value;
79 value.v_int64 = static_cast<int64_t>(arg);
80 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
81 e->tvmFuncArgValues.push_back(value);
82 e->tvmFuncArgTypes.push_back(kDLInt);
83 }
84
Java_org_apache_tvm_LibInfo_tvmFuncPushArgDouble(JNIEnv * env,jobject obj,jdouble arg)85 JNIEXPORT void JNICALL Java_org_apache_tvm_LibInfo_tvmFuncPushArgDouble(
86 JNIEnv *env, jobject obj, jdouble arg) {
87 TVMValue value;
88 value.v_float64 = static_cast<double>(arg);
89 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
90 e->tvmFuncArgValues.push_back(value);
91 e->tvmFuncArgTypes.push_back(kDLFloat);
92 }
93
Java_org_apache_tvm_LibInfo_tvmFuncPushArgString(JNIEnv * env,jobject obj,jstring arg)94 JNIEXPORT void JNICALL Java_org_apache_tvm_LibInfo_tvmFuncPushArgString(
95 JNIEnv *env, jobject obj, jstring arg) {
96 TVMValue value;
97 jstring garg = reinterpret_cast<jstring>(env->NewGlobalRef(arg));
98 value.v_str = env->GetStringUTFChars(garg, 0);
99 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
100 e->tvmFuncArgValues.push_back(value);
101 e->tvmFuncArgTypes.push_back(kStr);
102 // release string args later
103 e->tvmFuncArgPushedStrs.push_back(std::make_pair(garg, value.v_str));
104 }
105
Java_org_apache_tvm_LibInfo_tvmFuncPushArgHandle(JNIEnv * env,jobject obj,jlong arg,jint argType)106 JNIEXPORT void JNICALL Java_org_apache_tvm_LibInfo_tvmFuncPushArgHandle(
107 JNIEnv *env, jobject obj, jlong arg, jint argType) {
108 TVMValue value;
109 value.v_handle = reinterpret_cast<void *>(arg);
110 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
111 e->tvmFuncArgValues.push_back(value);
112 e->tvmFuncArgTypes.push_back(static_cast<int>(argType));
113 }
114
Java_org_apache_tvm_LibInfo_tvmFuncPushArgBytes(JNIEnv * env,jobject obj,jbyteArray arg)115 JNIEXPORT void JNICALL Java_org_apache_tvm_LibInfo_tvmFuncPushArgBytes(
116 JNIEnv *env, jobject obj, jbyteArray arg) {
117 jbyteArray garg = reinterpret_cast<jbyteArray>(env->NewGlobalRef(arg));
118 jbyte *data = env->GetByteArrayElements(garg, 0);
119
120 TVMByteArray *byteArray = new TVMByteArray();
121 byteArray->size = static_cast<size_t>(env->GetArrayLength(garg));
122 byteArray->data = reinterpret_cast<const char *>(data);
123
124 TVMValue value;
125 value.v_handle = reinterpret_cast<void *>(byteArray);
126
127 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
128 e->tvmFuncArgValues.push_back(value);
129 e->tvmFuncArgTypes.push_back(kBytes);
130
131 e->tvmFuncArgPushedBytes.push_back(std::make_pair(garg, byteArray));
132 // release (garg, data), byteArray later
133 }
134
Java_org_apache_tvm_LibInfo_tvmFuncListGlobalNames(JNIEnv * env,jobject obj,jobject jfuncNames)135 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncListGlobalNames(
136 JNIEnv *env, jobject obj, jobject jfuncNames) {
137 int outSize;
138 const char **outArray;
139
140 int ret = TVMFuncListGlobalNames(&outSize, &outArray);
141 if (ret) {
142 return ret;
143 }
144
145 jclass arrayClass = env->FindClass("java/util/List");
146 jmethodID arrayAppend = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z");
147
148 // fill names
149 for (int i = 0; i < outSize; ++i) {
150 jstring jname = env->NewStringUTF(outArray[i]);
151 env->CallBooleanMethod(jfuncNames, arrayAppend, jname);
152 env->DeleteLocalRef(jname);
153 }
154
155 env->DeleteLocalRef(arrayClass);
156
157 return ret;
158 }
159
Java_org_apache_tvm_LibInfo_tvmFuncFree(JNIEnv * env,jobject obj,jlong jhandle)160 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncFree(
161 JNIEnv *env, jobject obj, jlong jhandle) {
162 return TVMFuncFree(reinterpret_cast<TVMFunctionHandle>(jhandle));
163 }
164
Java_org_apache_tvm_LibInfo_tvmFuncGetGlobal(JNIEnv * env,jobject obj,jstring jname,jobject jhandle)165 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncGetGlobal(
166 JNIEnv *env, jobject obj, jstring jname, jobject jhandle) {
167 TVMFunctionHandle handle;
168 const char *name = env->GetStringUTFChars(jname, 0);
169 int ret = TVMFuncGetGlobal(name, &handle);
170 env->ReleaseStringUTFChars(jname, name);
171 setLongField(env, jhandle, reinterpret_cast<jlong>(handle));
172 return ret;
173 }
174
Java_org_apache_tvm_LibInfo_tvmFuncCall(JNIEnv * env,jobject obj,jlong jhandle,jobject jretVal)175 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncCall(
176 JNIEnv *env, jobject obj, jlong jhandle, jobject jretVal) {
177 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
178 int numArgs = e->tvmFuncArgValues.size();
179
180 TVMValue retVal;
181 int retTypeCode;
182
183 // function can be invoked recursively,
184 // thus we copy the pushed arguments here.
185 auto argValues = e->tvmFuncArgValues;
186 auto argTypes = e->tvmFuncArgTypes;
187 auto pushedStrs = e->tvmFuncArgPushedStrs;
188 auto pushedBytes = e->tvmFuncArgPushedBytes;
189
190 e->tvmFuncArgPushedStrs.clear();
191 e->tvmFuncArgPushedBytes.clear();
192 e->tvmFuncArgTypes.clear();
193 e->tvmFuncArgValues.clear();
194
195 int ret = TVMFuncCall(reinterpret_cast<TVMFunctionHandle>(jhandle),
196 &argValues[0], &argTypes[0], numArgs, &retVal, &retTypeCode);
197
198 if (ret != 0) {
199 return ret;
200 }
201
202 for (auto iter = pushedStrs.cbegin(); iter != pushedStrs.cend(); iter++) {
203 env->ReleaseStringUTFChars(iter->first, iter->second);
204 env->DeleteGlobalRef(iter->first);
205 }
206 for (auto iter = pushedBytes.cbegin(); iter != pushedBytes.cend(); iter++) {
207 env->ReleaseByteArrayElements(iter->first,
208 reinterpret_cast<jbyte *>(const_cast<char *>(iter->second->data)), 0);
209 env->DeleteGlobalRef(iter->first);
210 delete iter->second;
211 }
212
213 // return TVMValue object to Java
214 jclass refTVMValueCls = env->FindClass("org/apache/tvm/Base$RefTVMValue");
215 jfieldID refTVMValueFid
216 = env->GetFieldID(refTVMValueCls, "value", "Lorg/apache/tvm/TVMValue;");
217
218 env->SetObjectField(jretVal, refTVMValueFid, tvmRetValueToJava(env, retVal, retTypeCode));
219
220 env->DeleteLocalRef(refTVMValueCls);
221
222 return ret;
223 }
224
225 // Callback function
funcInvokeCallback(TVMValue * args,int * typeCodes,int numArgs,TVMRetValueHandle ret,void * resourceHandle)226 extern "C" int funcInvokeCallback(TVMValue *args,
227 int *typeCodes, int numArgs, TVMRetValueHandle ret, void *resourceHandle) {
228 JNIEnv *env;
229 int jniStatus = _jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
230 if (jniStatus == JNI_EDETACHED) {
231 #ifdef TVM4J_ANDROID
232 _jvm->AttachCurrentThread(&env, nullptr);
233 #else
234 _jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr);
235 #endif
236 } else {
237 CHECK(jniStatus == JNI_OK);
238 }
239
240 jclass tvmValueCls = env->FindClass("org/apache/tvm/TVMValue");
241 jobjectArray jargs = env->NewObjectArray(numArgs, tvmValueCls, 0);
242 for (int i = 0; i < numArgs; ++i) {
243 TVMValue arg = args[i];
244 int tcode = typeCodes[i];
245 if (tcode == kObjectHandle || tcode == kFuncHandle || tcode == kModuleHandle) {
246 TVMCbArgToReturn(&arg, tcode);
247 }
248 jobject jarg = tvmRetValueToJava(env, arg, tcode);
249 env->SetObjectArrayElement(jargs, i, jarg);
250 }
251
252 jclass clsFunc = env->FindClass("org/apache/tvm/Function");
253 jmethodID invokeRegisteredCbFunc = env->GetStaticMethodID(clsFunc, "invokeRegisteredCbFunc",
254 "(Lorg/apache/tvm/Function$Callback;[Lorg/apache/tvm/TVMValue;)Ljava/lang/Object;");
255 jmethodID pushArgToStack = env->GetStaticMethodID(clsFunc, "pushArgToStack",
256 "(Ljava/lang/Object;)V");
257
258 jobject jretValue = env->CallStaticObjectMethod(clsFunc, invokeRegisteredCbFunc,
259 reinterpret_cast<jobject>(resourceHandle), jargs);
260
261 TVMFuncArgsThreadLocalEntry *e = TVMFuncArgsThreadLocalStore::Get();
262 const size_t prevNumStrArg = e->tvmFuncArgPushedStrs.size();
263 const size_t prevNumBytesArg = e->tvmFuncArgPushedBytes.size();
264
265 // convert returned (java) TVMValue to (C) TVMValue
266 env->CallStaticVoidMethod(clsFunc, pushArgToStack, jretValue);
267
268 TVMValue retValue = e->tvmFuncArgValues.back();
269 e->tvmFuncArgValues.pop_back();
270
271 int retCode = e->tvmFuncArgTypes.back();
272 e->tvmFuncArgTypes.pop_back();
273
274 // set back the return value
275 TVMCFuncSetReturn(ret, &retValue, &retCode, 1);
276
277 // release allocated strings.
278 if (e->tvmFuncArgPushedStrs.size() > prevNumStrArg) {
279 const auto &pairArg = e->tvmFuncArgPushedStrs.back();
280 env->ReleaseStringUTFChars(pairArg.first, pairArg.second);
281 env->DeleteGlobalRef(pairArg.first);
282 e->tvmFuncArgPushedStrs.pop_back();
283 }
284 // release allocated bytes.
285 if (e->tvmFuncArgPushedBytes.size() > prevNumBytesArg) {
286 const auto &pairArg = e->tvmFuncArgPushedBytes.back();
287 env->ReleaseByteArrayElements(pairArg.first,
288 reinterpret_cast<jbyte *>(const_cast<char *>(pairArg.second->data)), 0);
289 env->DeleteGlobalRef(pairArg.first);
290 delete pairArg.second;
291 e->tvmFuncArgPushedBytes.pop_back();
292 }
293
294 env->DeleteLocalRef(clsFunc);
295 env->DeleteLocalRef(tvmValueCls);
296
297 return 0;
298 }
299
300 // Free callback function
funcFreeCallback(void * resourceHandle)301 extern "C" void funcFreeCallback(void *resourceHandle) {
302 JNIEnv *env;
303 int jniStatus = _jvm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
304 if (jniStatus == JNI_EDETACHED) {
305 #ifdef TVM4J_ANDROID
306 _jvm->AttachCurrentThread(&env, nullptr);
307 #else
308 _jvm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr);
309 #endif
310 } else {
311 CHECK(jniStatus == JNI_OK);
312 }
313 env->DeleteGlobalRef(reinterpret_cast<jobject>(resourceHandle));
314 }
315
Java_org_apache_tvm_LibInfo_tvmFuncCreateFromCFunc(JNIEnv * env,jobject obj,jobject jfunction,jobject jretHandle)316 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncCreateFromCFunc(
317 JNIEnv *env, jobject obj, jobject jfunction, jobject jretHandle) {
318 TVMFunctionHandle out;
319 int ret = TVMFuncCreateFromCFunc(reinterpret_cast<TVMPackedCFunc>(&funcInvokeCallback),
320 reinterpret_cast<void *>(env->NewGlobalRef(jfunction)),
321 reinterpret_cast<TVMPackedCFuncFinalizer>(&funcFreeCallback),
322 &out);
323 setLongField(env, jretHandle, reinterpret_cast<jlong>(out));
324 return ret;
325 }
326
Java_org_apache_tvm_LibInfo_tvmFuncRegisterGlobal(JNIEnv * env,jobject obj,jstring jname,jlong jhandle,jint joverride)327 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncRegisterGlobal(
328 JNIEnv *env, jobject obj, jstring jname, jlong jhandle, jint joverride) {
329 const char *name = env->GetStringUTFChars(jname, 0);
330 int ret = TVMFuncRegisterGlobal(
331 name, reinterpret_cast<TVMFunctionHandle>(jhandle), reinterpret_cast<int>(joverride));
332 env->ReleaseStringUTFChars(jname, name);
333 return ret;
334 }
335
336 // Module
Java_org_apache_tvm_LibInfo_tvmModFree(JNIEnv * env,jobject obj,jlong jhandle)337 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmModFree(
338 JNIEnv *env, jobject obj, jlong jhandle) {
339 return TVMModFree(reinterpret_cast<TVMModuleHandle>(jhandle));
340 }
341
Java_org_apache_tvm_LibInfo_tvmModImport(JNIEnv * env,jobject obj,jlong jmod,jlong jdep)342 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmModImport(
343 JNIEnv *env, jobject obj, jlong jmod, jlong jdep) {
344 return TVMModImport(reinterpret_cast<TVMModuleHandle>(jmod),
345 reinterpret_cast<TVMModuleHandle>(jdep));
346 }
347
Java_org_apache_tvm_LibInfo_tvmModGetFunction(JNIEnv * env,jobject obj,jlong jhandle,jstring jname,jint jimport,jobject jret)348 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmModGetFunction(
349 JNIEnv *env, jobject obj, jlong jhandle, jstring jname, jint jimport, jobject jret) {
350 TVMFunctionHandle retFunc;
351
352 const char *name = env->GetStringUTFChars(jname, 0);
353 int ret = TVMModGetFunction(reinterpret_cast<TVMFunctionHandle>(jhandle),
354 name,
355 reinterpret_cast<int>(jimport),
356 &retFunc);
357 env->ReleaseStringUTFChars(jname, name);
358
359 setLongField(env, jret, reinterpret_cast<jlong>(retFunc));
360
361 return ret;
362 }
363
364 // NDArray
Java_org_apache_tvm_LibInfo_tvmArrayFree(JNIEnv * env,jobject obj,jlong jhandle)365 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayFree(
366 JNIEnv *env, jobject obj, jlong jhandle) {
367 return TVMArrayFree(reinterpret_cast<TVMArrayHandle>(jhandle));
368 }
369
Java_org_apache_tvm_LibInfo_tvmArrayAlloc(JNIEnv * env,jobject obj,jlongArray jshape,jint jdtypeCode,jint jdtypeBits,jint jdtypeLanes,jint jdeviceType,jint jdeviceId,jobject jret)370 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayAlloc(
371 JNIEnv *env, jobject obj, jlongArray jshape, jint jdtypeCode,
372 jint jdtypeBits, jint jdtypeLanes, jint jdeviceType, jint jdeviceId, jobject jret) {
373 int ndim = static_cast<int>(env->GetArrayLength(jshape));
374
375 TVMArrayHandle out;
376
377 jlong *shapeArray = env->GetLongArrayElements(jshape, NULL);
378 int ret = TVMArrayAlloc(
379 reinterpret_cast<const tvm_index_t*>(shapeArray),
380 ndim,
381 static_cast<int>(jdtypeCode),
382 static_cast<int>(jdtypeBits),
383 static_cast<int>(jdtypeLanes),
384 static_cast<int>(jdeviceType),
385 static_cast<int>(jdeviceId),
386 &out);
387 env->ReleaseLongArrayElements(jshape, shapeArray, 0);
388
389 setLongField(env, jret, reinterpret_cast<jlong>(out));
390
391 return ret;
392 }
393
Java_org_apache_tvm_LibInfo_tvmArrayGetShape(JNIEnv * env,jobject obj,jlong jhandle,jobject jshape)394 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayGetShape(
395 JNIEnv *env, jobject obj, jlong jhandle, jobject jshape) {
396 TVMArray *array = reinterpret_cast<TVMArray *>(jhandle);
397 int64_t *shape = array->shape;
398 int ndim = array->ndim;
399
400 // fill shape buffer
401 jclass longClass = env->FindClass("java/lang/Long");
402 jmethodID newLong = env->GetMethodID(longClass, "<init>", "(J)V");
403
404 jclass arrayClass = env->FindClass("java/util/List");
405 jmethodID arrayAppend = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z");
406 for (int i = 0; i < ndim; ++i) {
407 jobject data = env->NewObject(longClass, newLong, static_cast<jlong>(shape[i]));
408 env->CallBooleanMethod(jshape, arrayAppend, data);
409 env->DeleteLocalRef(data);
410 }
411 env->DeleteLocalRef(longClass);
412 env->DeleteLocalRef(arrayClass);
413
414 return 0;
415 }
416
Java_org_apache_tvm_LibInfo_tvmArrayCopyFromTo(JNIEnv * env,jobject obj,jlong jfrom,jlong jto)417 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayCopyFromTo(
418 JNIEnv *env, jobject obj, jlong jfrom, jlong jto) {
419 return TVMArrayCopyFromTo(reinterpret_cast<TVMArrayHandle>(jfrom),
420 reinterpret_cast<TVMArrayHandle>(jto), NULL);
421 }
422
Java_org_apache_tvm_LibInfo_tvmArrayCopyFromJArray(JNIEnv * env,jobject obj,jbyteArray jarr,jlong jfrom,jlong jto)423 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayCopyFromJArray(
424 JNIEnv *env, jobject obj, jbyteArray jarr, jlong jfrom, jlong jto) {
425 jbyte *data = env->GetByteArrayElements(jarr, NULL);
426
427 TVMArray *from = reinterpret_cast<TVMArray *>(jfrom);
428 from->data = static_cast<void *>(data);
429
430 int ret = TVMArrayCopyFromTo(static_cast<TVMArrayHandle>(from),
431 reinterpret_cast<TVMArrayHandle>(jto), NULL);
432
433 from->data = NULL;
434 env->ReleaseByteArrayElements(jarr, data, 0);
435
436 return ret;
437 }
438
Java_org_apache_tvm_LibInfo_tvmArrayCopyToJArray(JNIEnv * env,jobject obj,jlong jfrom,jbyteArray jarr)439 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmArrayCopyToJArray(
440 JNIEnv *env, jobject obj, jlong jfrom, jbyteArray jarr) {
441 TVMArray *from = reinterpret_cast<TVMArray *>(jfrom);
442 int size = static_cast<int>(env->GetArrayLength(jarr));
443 jbyte *pdata = env->GetByteArrayElements(jarr, NULL);
444 int ret = 0;
445 if (memcpy(static_cast<void *>(pdata), from->data, size) == NULL) {
446 ret = 1;
447 }
448 env->ReleaseByteArrayElements(jarr, pdata, 0); // copy back to java array automatically
449 return ret;
450 }
451
452 // Context
Java_org_apache_tvm_LibInfo_tvmSynchronize(JNIEnv * env,jint deviceType,jint deviceId)453 JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmSynchronize(
454 JNIEnv *env, jint deviceType, jint deviceId) {
455 return TVMSynchronize(static_cast<int>(deviceType), static_cast<int>(deviceId), NULL);
456 }
457