add runstep java api and enable new java api

This commit is contained in:
zhengjun10 2021-12-18 17:30:33 +08:00
parent 623040dfb6
commit 61ef1388f0
7 changed files with 172 additions and 37 deletions

View File

@ -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

View File

@ -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;

View File

@ -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<MSTensor> 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<MSTensor> 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<String, MSTensor> outputs = session.getOutputMapByTensor();
for (MSTensor tensor : outputs.values()) {
List<MSTensor> 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<Integer> 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<Integer> labelsVec = new Vector<Integer>();
int totalSize = dataset.size();
List<MSTensor> inputs = session.getInputs();
List<MSTensor> 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();
}
}

View File

@ -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)

View File

@ -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'

View File

@ -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<Long> getOutputs(long modelPtr);
private native long getOutputByTensorName(long modelPtr, String tensorName);

View File

@ -275,6 +275,17 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_setTrainMode(JNIE
return static_cast<jboolean>(status.IsOk());
}
extern "C" JNIEXPORT jboolean JNICALL Java_com_mindspore_Model_runStep(JNIEnv *env, jobject thiz, jlong model_ptr) {
auto *pointer = reinterpret_cast<void *>(model_ptr);
if (pointer == nullptr) {
MS_LOGE("Model pointer from java is nullptr");
return jlong(false);
}
auto *lite_model_ptr = static_cast<mindspore::Model *>(pointer);
auto status = lite_model_ptr->RunStep(nullptr, nullptr);
return static_cast<jboolean>(status.IsOk());
}
std::vector<mindspore::MSTensor> convertArrayToVector(JNIEnv *env, jlongArray inputs) {
auto input_size = static_cast<int>(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<int>(env->GetArrayLength(features));
jlong *input_data = env->GetLongArrayElements(features, nullptr);
std::vector<mindspore::MSTensor> newFeatures;
for (int i = 0; i < size; ++i) {
auto *tensor_pointer = reinterpret_cast<void *>(input_data[i]);
if (tensor_pointer == nullptr) {
MS_LOGE("Tensor pointer from java is nullptr");
return false;
}
auto *ms_tensor_ptr = static_cast<mindspore::MSTensor *>(tensor_pointer);
newFeatures.emplace_back(*ms_tensor_ptr);
}
auto lite_model_ptr = reinterpret_cast<mindspore::Model *>(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, "<init>", "()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, "<init>", "(J)V");
auto *pointer = reinterpret_cast<void *>(model_ptr);
if (pointer == nullptr) {
MS_LOGE("Model pointer from java is nullptr");
return ret;
}
auto *lite_model_ptr = static_cast<mindspore::Model *>(pointer);
auto features = lite_model_ptr->GetFeatureMaps();
for (auto &feature : features) {
auto tensor_ptr = std::make_unique<mindspore::MSTensor>(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<void *>(model_ptr);
if (pointer == nullptr) {