diff --git a/mindspore/lite/build_lite.sh b/mindspore/lite/build_lite.sh index d1c8609d9a..8d4bd9ecac 100755 --- a/mindspore/lite/build_lite.sh +++ b/mindspore/lite/build_lite.sh @@ -109,9 +109,9 @@ build_lite_x86_64_jni_and_jar() { fi # build jar - ${LITE_JAVA_PATH}/java/gradlew clean -p ${LITE_JAVA_PATH}/java/linux_x86/ - ${LITE_JAVA_PATH}/java/gradlew releaseJar -p ${LITE_JAVA_PATH}/java/linux_x86/ - cp ${LITE_JAVA_PATH}/java/linux_x86/build/lib/jar/*.jar ${BASEPATH}/output/tmp/${pkg_name}/runtime/lib/ + ${LITE_JAVA_PATH}/java/gradlew clean -p ${LITE_JAVA_PATH}/ + ${LITE_JAVA_PATH}/java/gradlew releaseJar -p ${LITE_JAVA_PATH}/ + cp ${LITE_JAVA_PATH}/build/lib/jar/*.jar ${BASEPATH}/output/tmp/${pkg_name}/runtime/lib/ # package cd ${BASEPATH}/output/tmp @@ -413,6 +413,9 @@ build_aar() { # build common module ${LITE_JAVA_PATH}/java/gradlew clean -p ${LITE_JAVA_PATH}/java/common ${LITE_JAVA_PATH}/java/gradlew build -p ${LITE_JAVA_PATH}/java/common + # build new java api module + ${LITE_JAVA_PATH}/java/gradlew clean -p ${LITE_JAVA_PATH}/ + ${LITE_JAVA_PATH}/java/gradlew build -p ${LITE_JAVA_PATH}/ # build aar local npu_bak=${MSLITE_ENABLE_NPU} @@ -439,6 +442,7 @@ build_aar() { fi cp ${LITE_JAVA_PATH}/java/common/build/libs/mindspore-lite-java-common.jar ${LITE_JAVA_PATH}/java/app/libs + cp ${LITE_JAVA_PATH}/build/libs/mindspore-lite-java.jar ${LITE_JAVA_PATH}/java/app/libs ${LITE_JAVA_PATH}/java/gradlew clean -p ${LITE_JAVA_PATH}/java/app ${LITE_JAVA_PATH}/java/gradlew assembleRelease -p ${LITE_JAVA_PATH}/java/app ${LITE_JAVA_PATH}/java/gradlew publish -PLITE_VERSION=${VERSION_STR} -p ${LITE_JAVA_PATH}/java/app diff --git a/mindspore/lite/examples/quick_start_flclient/src/main/java/com/mindspore/flclient/demo/albert/AlbertDataSet.java b/mindspore/lite/examples/quick_start_flclient/src/main/java/com/mindspore/flclient/demo/albert/AlbertDataSet.java index 1647abe0a4..f564820d84 100644 --- a/mindspore/lite/examples/quick_start_flclient/src/main/java/com/mindspore/flclient/demo/albert/AlbertDataSet.java +++ b/mindspore/lite/examples/quick_start_flclient/src/main/java/com/mindspore/flclient/demo/albert/AlbertDataSet.java @@ -16,9 +16,7 @@ package com.mindspore.flclient.demo.albert; -import com.mindspore.flclient.model.CustomTokenizer; import com.mindspore.flclient.model.DataSet; -import com.mindspore.flclient.model.Feature; import com.mindspore.flclient.model.RunType; import com.mindspore.flclient.model.Status; diff --git a/mindspore/lite/examples/train_lenet_java/src/main/java/com/mindspore/lite/train_lenet/NetRunner.java b/mindspore/lite/examples/train_lenet_java/src/main/java/com/mindspore/lite/train_lenet/NetRunner.java index 1bdf74a4bb..6052417c67 100644 --- a/mindspore/lite/examples/train_lenet_java/src/main/java/com/mindspore/lite/train_lenet/NetRunner.java +++ b/mindspore/lite/examples/train_lenet_java/src/main/java/com/mindspore/lite/train_lenet/NetRunner.java @@ -16,21 +16,22 @@ package com.mindspore.lite.train_lenet; -import com.mindspore.lite.MSTensor; -import com.mindspore.lite.LiteSession; -import com.mindspore.lite.TrainSession; -import com.mindspore.lite.config.MSConfig; +import com.mindspore.Model; +import com.mindspore.Graph; +import com.mindspore.MSTensor; +import com.mindspore.config.DeviceType; +import com.mindspore.config.MSContext; +import com.mindspore.config.TrainCfg; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; -import java.util.Map; import java.util.Vector; public class NetRunner { private int dataIndex = 0; private int labelIndex = 1; - private LiteSession session; + private Model liteModel; private long batchSize; private long dataSize; // one input data size, in byte private DataSet ds = new DataSet(); @@ -41,19 +42,25 @@ public class NetRunner { private String trainedFilePath = "trained.ms"; public void initAndFigureInputs(String modelPath, int virtualBatchSize) { - MSConfig msConfig = new MSConfig(); - // arg 0: DeviceType:DT_CPU -> 0 - // arg 1: ThreadNum -> 2 - // arg 2: cpuBindMode:NO_BIND -> 0 - // arg 3: enable_fp16 -> false - msConfig.init(0, 2, 0, false); - session = new LiteSession(); + Graph graph = new Graph(); + boolean isSuccess = graph.Load(modelPath); + if (!isSuccess) { + System.out.println("Graph load failed"); + } System.out.println("Model path is " + modelPath); - session = TrainSession.createTrainSession(modelPath, msConfig, false); - virtualBatch = virtualBatchSize; - session.setupVirtualBatch(virtualBatch, 0.01f, 1.00f); + TrainCfg cfg = new TrainCfg(); + cfg.init(); - List inputs = session.getInputs(); + MSContext context = new MSContext(); + context.init(1, 0); + context.addDeviceInfo(DeviceType.DT_CPU, false, 0); + liteModel = new Model(); + isSuccess = liteModel.build(graph, context, cfg); + if (!isSuccess) { + System.out.println("model build failed failed"); + } + virtualBatch = virtualBatchSize; + List inputs = liteModel.getInputs(); if (inputs.size() <= 1) { System.err.println("model input size: " + inputs.size()); return; @@ -98,8 +105,8 @@ public class NetRunner { } private MSTensor searchOutputsForSize(int size) { - Map outputs = session.getOutputMapByTensor(); - for (MSTensor tensor : outputs.values()) { + List outputs = liteModel.getOutputs(); + for (MSTensor tensor : outputs) { if (tensor.elementsNum() == size) { return tensor; } @@ -109,13 +116,13 @@ public class NetRunner { } public int trainLoop() { - session.train(); + liteModel.setTrainMode(true); float min_loss = 1000; float max_acc = 0; for (int i = 0; i < cycles; i++) { for (int b = 0; b < virtualBatch; b++) { fillInputData(ds.getTrainData(), false); - session.runGraph(); + liteModel.runStep(); float loss = getLoss(); if (min_loss > loss) { min_loss = loss; @@ -125,7 +132,8 @@ public class NetRunner { if (max_acc < acc) { max_acc = acc; } - System.out.println("step_" + (i + 1) + ": \tLoss is " + loss + " [min=" + min_loss + "]" + " max_accc=" + max_acc); + System.out.println("step_" + (i + 1) + ": \tLoss is " + loss + " [min=" + min_loss + "]" + " " + + "max_accc=" + max_acc); } } } @@ -139,14 +147,14 @@ public class NetRunner { if (maxTests != -1 && tests < maxTests) { tests = maxTests; } - session.eval(); + liteModel.setTrainMode(false); for (long i = 0; i < tests; i++) { Vector labels = fillInputData(test_set, (maxTests == -1)); if (labels.size() != batchSize) { System.err.println("unexpected labels size: " + labels.size() + " batch_size size: " + batchSize); System.exit(1); } - session.runGraph(); + liteModel.runStep(); MSTensor outputsv = searchOutputsForSize((int) (batchSize * numOfClasses)); if (outputsv == null) { System.err.println("can not find output tensor with size: " + batchSize * numOfClasses); @@ -168,7 +176,7 @@ public class NetRunner { } } } - session.train(); + liteModel.setTrainMode(true); accuracy /= (batchSize * tests); return accuracy; } @@ -178,7 +186,7 @@ public class NetRunner { Vector labelsVec = new Vector(); int totalSize = dataset.size(); - List inputs = session.getInputs(); + List inputs = liteModel.getInputs(); int inputDataCnt = inputs.get(dataIndex).elementsNum(); float[] inputBatchData = new float[inputDataCnt]; @@ -196,7 +204,8 @@ public class NetRunner { int label = 0; DataSet.DataLabelTuple dataLabelTuple = dataset.get(idx); label = dataLabelTuple.label; - System.arraycopy(dataLabelTuple.data, 0, inputBatchData, (int) (i * dataLabelTuple.data.length), dataLabelTuple.data.length); + System.arraycopy(dataLabelTuple.data, 0, inputBatchData, (int) (i * dataLabelTuple.data.length), + dataLabelTuple.data.length); labelBatchData[i] = label; labelsVec.add(label); } @@ -230,16 +239,13 @@ public class NetRunner { System.out.println("accuracy = " + acc); if (cycles > 0) { - // arg 0: FileName - // arg 1: model type MT_TRAIN -> 0 - // arg 2: quantization type QT_DEFAULT -> 0 - if (session.export(trainedFilePath, 0, 0)) { + if (liteModel.export(trainedFilePath, 0, false, null)) { System.out.println("Trained model successfully saved: " + trainedFilePath); } else { System.err.println("Save model error."); } } - session.free(); + liteModel.free(); } } diff --git a/mindspore/lite/java/build.gradle b/mindspore/lite/java/build.gradle new file mode 100644 index 0000000000..cc6b824dd6 --- /dev/null +++ b/mindspore/lite/java/build.gradle @@ -0,0 +1,36 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + google() + jcenter() + mavenCentral() + } + dependencies { + classpath "com.android.tools.build:gradle:4.0.0" + } +} + +allprojects { + repositories { + google() + jcenter() + mavenCentral() + } +} + +apply plugin: 'java' + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation project(':linux_x86') +} + +archivesBaseName = 'mindspore-lite-java' + +task releaseJar(type: Jar) { + from('java/common/build/classes/java/main') + from('java/linux_x86/build/classes/java/main') + from('build/classes/java/main') + destinationDirectory = file('build/lib/jar') +} +releaseJar.dependsOn(build) \ No newline at end of file diff --git a/mindspore/lite/java/settings.gradle b/mindspore/lite/java/settings.gradle new file mode 100644 index 0000000000..37af76fa35 --- /dev/null +++ b/mindspore/lite/java/settings.gradle @@ -0,0 +1,13 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.6/userguide/multi_project_builds.html + */ +include ':common' +project(':common').projectDir = new File(settingsDir,'./java/common') +include ':linux_x86' +project(':linux_x86').projectDir = new File(settingsDir,'./java/linux_x86') +rootProject.name = 'mindspore-lite-java' \ No newline at end of file diff --git a/mindspore/lite/java/src/main/java/com/mindspore/Model.java b/mindspore/lite/java/src/main/java/com/mindspore/Model.java index 0709738a68..99c8c199c3 100644 --- a/mindspore/lite/java/src/main/java/com/mindspore/Model.java +++ b/mindspore/lite/java/src/main/java/com/mindspore/Model.java @@ -109,6 +109,24 @@ public class Model { return modelPtr != 0; } + /** + * Execute predict. + * + * @return predict status. + */ + public boolean predict() { + return this.runStep(modelPtr); + } + + /** + * Run Model by step. + * + * @return run model status.work in train mode. + */ + public boolean runStep() { + return this.runStep(modelPtr); + } + /** * Resize inputs shape. * @@ -258,6 +276,8 @@ public class Model { private native long getInputByTensorName(long modelPtr, String tensorName); + private native boolean runStep(long modelPtr); + private native List getOutputs(long modelPtr); private native long getOutputByTensorName(long modelPtr, String tensorName); diff --git a/mindspore/lite/java/src/main/native/model.cpp b/mindspore/lite/java/src/main/native/model.cpp index 4ed0eeb490..e827c257fb 100644 --- a/mindspore/lite/java/src/main/native/model.cpp +++ b/mindspore/lite/java/src/main/native/model.cpp @@ -275,6 +275,17 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_setTrainMode(JNIE return static_cast(status.IsOk()); } +extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_runStep(JNIEnv *env, jobject thiz, jlong model_ptr) { + auto *pointer = reinterpret_cast(model_ptr); + if (pointer == nullptr) { + MS_LOGE("Model pointer from java is nullptr"); + return jlong(false); + } + auto *lite_model_ptr = static_cast(pointer); + auto status = lite_model_ptr->RunStep(nullptr, nullptr); + return static_cast(status.IsOk()); +} + std::vector convertArrayToVector(JNIEnv *env, jlongArray inputs) { auto input_size = static_cast(env->GetArrayLength(inputs)); jlong *input_data = env->GetLongArrayElements(inputs, nullptr); @@ -377,6 +388,53 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_export(JNIEnv *en return (jboolean)(ret.IsOk()); } +extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_updateFeatureMaps(JNIEnv *env, jclass, jlong model_ptr, + jlongArray features) { + auto size = static_cast(env->GetArrayLength(features)); + jlong *input_data = env->GetLongArrayElements(features, nullptr); + std::vector newFeatures; + for (int i = 0; i < size; ++i) { + auto *tensor_pointer = reinterpret_cast(input_data[i]); + if (tensor_pointer == nullptr) { + MS_LOGE("Tensor pointer from java is nullptr"); + return false; + } + auto *ms_tensor_ptr = static_cast(tensor_pointer); + newFeatures.emplace_back(*ms_tensor_ptr); + } + auto lite_model_ptr = reinterpret_cast(model_ptr); + auto ret = lite_model_ptr->UpdateFeatureMaps(newFeatures); + return (jboolean)(ret.IsOk()); +} + +extern "C" JNIEXPORT jobject JNICALL Java_com_mindspore_Model_getFeatureMaps(JNIEnv *env, jobject thiz, + jlong model_ptr) { + jclass array_list = env->FindClass("java/util/ArrayList"); + jmethodID array_list_construct = env->GetMethodID(array_list, "", "()V"); + jobject ret = env->NewObject(array_list, array_list_construct); + jmethodID array_list_add = env->GetMethodID(array_list, "add", "(Ljava/lang/Object;)Z"); + + jclass long_object = env->FindClass("java/lang/Long"); + jmethodID long_object_construct = env->GetMethodID(long_object, "", "(J)V"); + auto *pointer = reinterpret_cast(model_ptr); + if (pointer == nullptr) { + MS_LOGE("Model pointer from java is nullptr"); + return ret; + } + auto *lite_model_ptr = static_cast(pointer); + auto features = lite_model_ptr->GetFeatureMaps(); + for (auto &feature : features) { + auto tensor_ptr = std::make_unique(feature); + if (tensor_ptr == nullptr) { + MS_LOGE("Make ms tensor failed"); + return ret; + } + jobject tensor_addr = env->NewObject(long_object, long_object_construct, jlong(tensor_ptr.release())); + env->CallBooleanMethod(ret, array_list_add, tensor_addr); + } + return ret; +} + extern "C" JNIEXPORT void JNICALL Java_com_mindspore_Model_free(JNIEnv *env, jobject thiz, jlong model_ptr) { auto *pointer = reinterpret_cast(model_ptr); if (pointer == nullptr) {