Skip to content
Snippets Groups Projects
Commit 9137345c authored by zhou_lili's avatar zhou_lili
Browse files

change om to mindir for naml

parent 1bc514df
No related branches found
No related tags found
No related merge requests found
Showing
with 720 additions and 1557 deletions
......@@ -43,14 +43,14 @@ category_embedding_dim: 112
query_vector_dim: 208
n_filters: 400
window_size: 3
checkpoint_path: ""
batch_size: 64
checkpoint_path: "naml/naml_large_new.ckpt"
batch_size: 16
# train option
beta1: 0.9
beta2: 0.999
epsilon: 0.00000001 # 1e-8
neg_sample: 4
neg_sample: -1 #when training, neg_sample=4, when test, neg_sample=-1
mixed: True
sink_mode: True
weight_decay: True
......@@ -63,9 +63,14 @@ eval_neg_sample: -1
# export option
export_file_dir: "./"
file_format: "AIR"
file_format: "MINDIR"
export_neg_sample: -1
# infer option
preprocess_path: "./"
result_path: "./"
label_path: "./"
---
# Help description for each configuration
......
......@@ -53,11 +53,11 @@ You can download the dataset and put the directory in structure as follows:
├── naml
├── README.md # descriptions about NAML
├── model_utils
│ ├──__init__.py // module init file
│ ├──config.py // Parse arguments
│ ├──device_adapter.py // Device adapter for ModelArts
│ ├──local_adapter.py // Local adapter
│ ├──moxing_adapter.py // Moxing adapter for ModelArts
│ ├──__init__.py # module init file
│ ├──config.py # Parse arguments
│ ├──device_adapter.py # Device adapter for ModelArts
│ ├──local_adapter.py # Local adapter
│ ├──moxing_adapter.py # Moxing adapter for ModelArts
├── scripts
│ ├──run_distribute_train.sh # shell script for distribute training
│ ├──run_train.sh # shell script for training
......@@ -76,7 +76,8 @@ You can download the dataset and put the directory in structure as follows:
├── train.py # training script
├── eval.py # evaluation script
├── export.py # export mindir script
└── postprogress.py # post process for 310 inference
├── preprocess.py # preprocess input data
└── postprocess.py # post process for 310 inference
```
## [Training process](#contents)
......@@ -200,6 +201,17 @@ python export.py --platform [PLATFORM] --checkpoint_path [CHECKPOINT_PATH] --fil
- `EXPORT_FORMAT` should be in ["AIR", "MINDIR"]
## [Infer on Ascend310](#contents)
```shell
# Ascend310 inference
bash run_infer_310.sh [NEWS_MODEL] [USER_MODEL] [DEVICE_ID]
```
- `NEWS_MODEL` specifies path of news "MINDIR" OR "AIR" model.
- `USER_MODEL` specifies path of user "MINDIR" OR "AIR" model.
- `DEVICE_ID` is optional, default value is 0.
# [Model Description](#contents)
## [Performance](#contents)
......@@ -239,12 +251,12 @@ python export.py --platform [PLATFORM] --checkpoint_path [CHECKPOINT_PATH] --fil
| ------------------- | --------------------------- |
| Model Version | NAML |
| Resource | Ascend 310 |
| Uploaded Date | 03/13/2021 (month/day/year) |
| MindSpore Version | 1.2.0 |
| Uploaded Date | 12/10/2021 (month/day/year) |
| MindSpore Version | 1.6.0 |
| Dataset | MINDlarge |
| batch_size | 64 |
| batch_size | 16 |
| outputs | probability |
| Accuracy | AUC: 0.667 |
| Accuracy | AUC: 0.6669 |
# [Description of Random Situation](#contents)
......
# Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
# CMake lowest version requirement
cmake_minimum_required(VERSION 3.5.1)
# project information
project(ACL_RESNET50)
find_package(gflags REQUIRED)
include_directories(${gflags_INCLUDE_DIR})
# Compile options
add_compile_options(-std=c++11 -g -O0)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../out")
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O0 -g -Wall")
set(INC_PATH $ENV{DDK_PATH})
if(NOT DEFINED ENV{DDK_PATH})
set(INC_PATH "/usr/local/Ascend")
message(STATUS "set default INC_PATH: ${INC_PATH}")
else()
message(STATUS "env INC_PATH: ${INC_PATH}")
endif()
set(LIB_PATH $ENV{NPU_HOST_LIB})
if(NOT DEFINED ENV{NPU_HOST_LIB})
set(LIB_PATH "/usr/local/Ascend/acllib/lib64/stub/")
message(STATUS "set default LIB_PATH: ${LIB_PATH}")
else()
message(STATUS "env LIB_PATH: ${LIB_PATH}")
endif()
# Header path
include_directories(
${INC_PATH}/acllib/include/
../include/
)
# add host lib path
link_directories(
${LIB_PATH}
)
# Set output directory
cmake_minimum_required(VERSION 3.14.1)
project(Ascend310Infer)
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
# Set include directory and library directory
set(ACL_LIB_DIR $ENV{ASCEND_HOME}/fwkacllib)
set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/fwkacllib)
# Header path
include_directories(${ACL_LIB_DIR}/include/)
include_directories(${ATLAS_ACL_LIB_DIR}/include/)
include_directories(${PROJECT_SRC_ROOT}/../inc)
# add host lib path
link_directories(${ACL_LIB_DIR})
find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64)
find_library(stdc libstdc++.so.6 /usr/)
add_executable(main
./src/utils.cpp
./src/model_process.cpp
./src/sample_process.cpp
./src/main.cpp)
target_link_libraries(main ${acl} ${stdc} gflags)
install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
include_directories(${PROJECT_SRC_ROOT})
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)
add_executable(main src/main.cc src/utils.cc)
target_link_libraries(main ${MS_LIB} ${MD_LIB} gflags)
......@@ -13,11 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
if [ ! -d out ]; then
mkdir out
if [ -d out ]; then
rm -rf out
fi
mkdir out
cd out || exit
export CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0
cmake .. -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE
if [ -f "Makefile" ]; then
make clean
fi
cmake .. \
-DMINDSPORE_PATH="`pip3.7 show mindspore-ascend | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`"
make
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_MODEL_ZOO_NAML_MODEL_PROCESS_H_
#define MINDSPORE_MODEL_ZOO_NAML_MODEL_PROCESS_H_
#pragma once
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include "./utils.h"
#include "acl/acl.h"
class ModelProcess {
public:
ModelProcess() = default;
ModelProcess(const std::string &inputDataPath, const std::string &idFilePath, uint32_t batchSize);
~ModelProcess();
Result LoadModelFromFileWithMem(const char *modelPath);
void Unload();
Result CreateDesc();
void DestroyDesc();
void DestroyInput();
Result CreateOutput();
void DestroyOutput();
Result Execute(uint32_t index);
void OutputModelResult();
Result CreateInput();
Result CpyFileToDevice(std::string fileName, uint32_t inputNum);
void CpyOutputFromDeviceToHost(uint32_t index);
std::map<int, void *> GetResult();
std::vector<uint32_t> GetOutputSize();
std::vector<uint32_t> GetInputSize();
Result ExecuteWithFile(uint32_t fileNum);
Result CpyDataToDevice(void *data, uint32_t len, uint32_t inputNum);
std::string GetInputDataPath();
std::string GetCostTimeInfo();
void DestroyResource();
std::vector<std::vector<void *>> ReadInputFiles(std::vector<std::vector<std::string>> inputFiles,
size_t inputSize, std::vector<std::vector<uint32_t>> *fileSize);
Result ReadIdFiles();
Result InitResource();
uint32_t ReadFiles();
private:
uint32_t modelId_;
std::map<double, double> costTime_map_;
size_t modelMemSize_;
size_t modelWeightSize_;
void *modelMemPtr_;
void *modelWeightPtr_;
uint32_t batchSize_;
bool loadFlag_; // model load flag
aclmdlDesc *modelDesc_;
aclmdlDataset *input_;
uint32_t inputNum_;
std::vector<uint32_t> inputBuffSize_;
aclmdlDataset *output_;
uint32_t outputNum_;
std::vector<uint32_t> outputBuffSize_;
std::map<int, void *> result_;
std::string inputDataPath_;
std::string idFilePath_;
std::vector<std::vector<void *>> fileBuff_;
std::vector<std::vector<uint32_t>> fileSize_;
std::vector<std::vector<int>> ids_;
};
#endif
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_MODEL_ZOO_NAML_SAMPLE_PROCESS_H_
#define MINDSPORE_MODEL_ZOO_NAML_SAMPLE_PROCESS_H_
#pragma once
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "acl/acl.h"
#include "./utils.h"
#include "./model_process.h"
class SampleProcess {
public:
SampleProcess();
SampleProcess(uint32_t deviceId, uint32_t threadNum);
~SampleProcess();
Result InitResource();
Result Process(const std::vector<std::string> &omPaths,
const std::vector<std::string> &inputDataPaths,
const std::vector<std::string> &inputIdPaths,
const std::string &browsedNewsPath,
uint32_t batchSize);
Result CreateModelProcessInstance(const std::vector<std::string> &omPaths,
const std::vector<std::string> &inputDataPaths,
const std::vector<std::string> &inputIdPaths, uint32_t batchSize,
std::map<int, std::shared_ptr<ModelProcess>> *modelProcessContainer);
Result GetPred(std::map<int, std::shared_ptr<ModelProcess>> *modelProcessContainer, uint32_t fileNum);
int WriteResult(const std::string& imageFile, std::vector<float> result, uint32_t size);
std::vector<std::string> GetModelExecCostTimeInfo();
std::vector<std::vector<std::vector<int>>> ReadHistory(std::vector<std::string> historyFile, uint32_t batchSize);
Result ReadBrowsedFile(const std::string &browsedNewsPath, std::vector<std::string> userIdFiles,
std::vector<std::vector<int>> *usersIds, std::vector<std::vector<int>> *candidateNewsIds);
uint32_t ReadBrowsedData(const std::string &browsedNewsPath);
void GetResult(uint32_t startPos, uint32_t endPos,
std::map<int, void *> newsEncodeResult,
std::map<int, void *> userEncodeResult);
private:
void DestroyResource();
int32_t deviceId_;
aclrtContext context_;
aclrtStream stream_;
std::map<double, double> secondModelCostTime_map_;
std::map<double, double> thirdModelCostTime_map_;
std::map<double, double> totalCostTime_map_;
std::vector<std::vector<int>> usersIds_;
std::vector<std::vector<int>> candidateNewsIds_;
std::vector<std::string> userIdFiles_;
std::vector<std::string> time_cost_;
uint32_t threadNum_;
std::mutex mtx_;
};
#endif
......@@ -14,43 +14,19 @@
* limitations under the License.
*/
#ifndef MINDSPORE_MODEL_ZOO_NAML_UTILS_H_
#define MINDSPORE_MODEL_ZOO_NAML_UTILS_H_
#ifndef MINDSPORE_INFERENCE_UTILS_H_
#define MINDSPORE_INFERENCE_UTILS_H_
#pragma once
#include <sys/stat.h>
#include <dirent.h>
#include <iostream>
#include <vector>
#include <string>
#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
typedef enum Result {
SUCCESS = 0,
FAILED = 1
} Result;
class Utils {
public:
static void *GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize);
static void *ReadBinFile(std::string fileName, uint32_t *fileSize);
static std::vector <std::vector<std::string>> GetAllInputData(std::string dir_name);
static DIR *OpenDir(std::string dir_name);
static std::string RealPath(std::string path);
static std::vector <std::string> GetAllBins(std::string dir_name);
static Result ReadFileToVector(std::string newsIdFileName, uint32_t batchSize, std::vector<int> *newsId);
static Result ReadFileToVector(std::string newsIdFileName, std::vector<int> *newsId);
static Result ReadFileToVector(std::string newsIdFileName, uint32_t batchSize, uint32_t count,
std::vector<std::vector<int>> *newsId);
};
#pragma once
#include <memory>
#include "include/api/types.h"
std::vector<std::string> GetAllFiles(std::string_view dirName);
DIR *OpenDir(std::string_view dirName);
std::string RealPath(std::string_view path);
mindspore::MSTensor ReadFileToTensor(const std::string &file);
int WriteResult(const std::string& imageFile, const std::vector<mindspore::MSTensor> &outputs);
#endif
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/time.h>
#include <gflags/gflags.h>
#include <dirent.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <iosfwd>
#include <vector>
#include <fstream>
#include <sstream>
#include "include/api/model.h"
#include "include/api/context.h"
#include "include/api/types.h"
#include "include/api/serialization.h"
#include "include/dataset/execute.h"
#include "include/dataset/vision.h"
#include "inc/utils.h"
using mindspore::Context;
using mindspore::Serialization;
using mindspore::Model;
using mindspore::Status;
using mindspore::MSTensor;
using mindspore::dataset::Execute;
using mindspore::ModelType;
using mindspore::GraphCell;
using mindspore::kSuccess;
//***** bs=16 *****//
DEFINE_string(news_mindir, "./", "om model path.");
DEFINE_string(user_mindir, "./", "om model path.");
DEFINE_int32(batch_size, 16, "batch size");
DEFINE_int32(device_id, 0, "device id");
DEFINE_string(base_path, "./", "dataset base path.");
std::vector<std::string> news_input0_0_files;
auto context = std::make_shared<Context>();
struct timeval total_start;
struct timeval total_end;
std::map<double, double> model0_cost_time;
std::map<double, double> model1_cost_time;
int InitModel(const std::string &model_path, Model *model) {
mindspore::Graph graph;
Serialization::Load(model_path, ModelType::kMindIR, &graph);
Status ret = model->Build(GraphCell(graph), context);
if (ret != kSuccess) {
std::cout << "ERROR: Build model failed." << std::endl;
return 1;
}
return 0;
}
void GetAveTime(const std::map<double, double> &costTime_map, int *inferCount, double *average) {
for (auto iter = costTime_map.begin(); iter != costTime_map.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
(*average) += diff;
(*inferCount)++;
}
(*average) /= (*inferCount);
return;
}
void InitInputs(size_t input_index, const std::vector<MSTensor> &model0_inputs, std::vector<MSTensor> *inputs) {
std::string news_dataset_path = FLAGS_base_path + "/news_test_data";
auto file0_name = news_dataset_path + "/00_category_data/naml_news_" + std::to_string(input_index) + ".bin";
auto file1_name = news_dataset_path + "/01_subcategory_data/naml_news_" + std::to_string(input_index) + ".bin";
auto file2_name = news_dataset_path + "/02_title_data/naml_news_" + std::to_string(input_index) + ".bin";
auto file3_name = news_dataset_path + "/03_abstract_data/naml_news_" + std::to_string(input_index) + ".bin";
auto news_input0 = ReadFileToTensor(file0_name);
auto news_input1 = ReadFileToTensor(file1_name);
auto news_input2 = ReadFileToTensor(file2_name);
auto news_input3 = ReadFileToTensor(file3_name);
inputs->emplace_back(model0_inputs[0].Name(), model0_inputs[0].DataType(), model0_inputs[0].Shape(),
news_input0.Data().get(), news_input0.DataSize());
inputs->emplace_back(model0_inputs[1].Name(), model0_inputs[1].DataType(), model0_inputs[1].Shape(),
news_input1.Data().get(), news_input1.DataSize());
inputs->emplace_back(model0_inputs[2].Name(), model0_inputs[2].DataType(), model0_inputs[2].Shape(),
news_input2.Data().get(), news_input2.DataSize());
inputs->emplace_back(model0_inputs[3].Name(), model0_inputs[3].DataType(), model0_inputs[3].Shape(),
news_input3.Data().get(), news_input3.DataSize());
return;
}
void InitNewsDict(const std::vector<std::string> &news_input0_0_files, const std::vector<MSTensor> &model0_inputs,
std::map<uint32_t, MSTensor> *news_dict, Model *model0) {
int count = 0;
for (size_t i = 0; i < news_input0_0_files.size() - 1; ++i) {
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
std::vector <MSTensor> inputs0;
std::vector <MSTensor> outputs0;
// init inputs by model0 input for each iter
InitInputs(i, model0_inputs, &inputs0);
// get model0 outputs
gettimeofday(&total_start, nullptr);
gettimeofday(&start, nullptr);
Status ret0 = model0->Predict(inputs0, &outputs0);
gettimeofday(&end, nullptr);
if (ret0 != kSuccess) {
std::cout << "ERROR: Predict model0 failed." << std::endl;
return;
}
// init news_dict
auto file_name = FLAGS_base_path + "/news_id_data/naml_news_" + std::to_string(count++) + ".bin";
auto nid = ReadFileToTensor(file_name);
auto nid_addr = reinterpret_cast<uint32_t *>(nid.MutableData());
// output0 size is 1, shape: batch_size * 400
auto outputs0_addr = reinterpret_cast<float *>(outputs0[0].MutableData());
for (int k = 0; k < FLAGS_batch_size; ++k) {
MSTensor ret("", mindspore::DataType::kNumberTypeFloat32, {400}, nullptr, sizeof(float)* 400);
uint32_t *addr = reinterpret_cast<uint32_t *>(ret.MutableData());
memcpy(addr, outputs0_addr, 400 * sizeof(float));
(*news_dict)[nid_addr[k]] = ret;
outputs0_addr += 400;
}
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
model0_cost_time.insert(std::pair<double, double>(startTime_ms, endTime_ms));
}
std::cout << "=========InitNewsDict end" << std::endl;
return;
}
void InitUserDict(const std::vector<std::string> &history_input_files, const std::map<uint32_t, MSTensor> &news_dict,
std::map<uint32_t, MSTensor> *user_dict, Model *model1) {
int count = 0;
int uid_count = 0;
for (size_t i = 0; i < history_input_files.size() - 1; ++i) {
// model1, get model1 outputs
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
std::vector<MSTensor> outputs1;
int64_t size = FLAGS_batch_size * 50 * 400 * sizeof(float);
MSTensor buffer("", mindspore::DataType::kNumberTypeFloat32, {FLAGS_batch_size, 50, 400}, nullptr, size);
uint8_t *addr = reinterpret_cast<uint8_t *>(buffer.MutableData());
auto file_name = FLAGS_base_path + "/users_test_data/01_history_data/naml_users_" +
std::to_string(count++) + ".bin";
auto nid = ReadFileToTensor(file_name);
auto nid_addr = reinterpret_cast<uint32_t *>(nid.MutableData());
for (int j = 0; j < FLAGS_batch_size; ++j) {
for (int k = 0; k < 50; ++k) {
if (news_dict.find(nid_addr[k]) == news_dict.end()) {
addr += 400 * sizeof(float);
continue;
}
auto ms_tensor = news_dict.at(nid_addr[k]);
uint32_t *new_dict_data = reinterpret_cast<uint32_t *>(ms_tensor.MutableData());
if (addr == nullptr || new_dict_data == nullptr) {
std::cout << "addr is nullptr or new_dict_data is nullptr"
<< "src is: " << &new_dict_data << " dst is: " << &addr << std::endl;
return;
}
memcpy(addr, new_dict_data, 400 * sizeof(float));
addr += 400 * sizeof(float);
}
nid_addr += 50;
}
gettimeofday(&start, nullptr);
Status ret1 = model1->Predict({buffer}, &outputs1);
gettimeofday(&end, nullptr);
if (ret1 != kSuccess) {
std::cout << "ERROR: Predict model1 failed." << std::endl;
return;
}
// init user_dict
auto file_name1 = FLAGS_base_path + "/users_test_data/00_user_id_data/naml_users_" +
std::to_string(uid_count++) + ".bin";
auto nid1 = ReadFileToTensor(file_name1);
auto nid_addr1 = reinterpret_cast<uint32_t *>(nid1.MutableData());
auto outputs1_addr = reinterpret_cast<float *>(outputs1[0].MutableData());
for (int k = 0; k < FLAGS_batch_size; ++k) {
MSTensor ret("", mindspore::DataType::kNumberTypeFloat32, {400}, nullptr, sizeof(float) * 400);
uint32_t *addr1 = reinterpret_cast<uint32_t *>(ret.MutableData());
memcpy(addr1, outputs1_addr, 400 * sizeof(float));
addr1 += 400;
(*user_dict)[nid_addr1[k]] = ret;
outputs1_addr += 400;
}
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
model1_cost_time.insert(std::pair<double, double>(startTime_ms, endTime_ms));
}
std::cout << "=========InitUserDict end" << std::endl;
return;
}
void InitPred(const std::map<uint32_t, MSTensor> &news_dict, const std::map<uint32_t, MSTensor> &user_dict) {
std::string browsed_news_path = FLAGS_base_path + "/browsed_news_test_data";
std::string file1_path = browsed_news_path + "/01_candidate_nid_data";
auto eval_candidate_news = GetAllFiles(file1_path);
for (size_t i = 0; i < eval_candidate_news.size() - 1; ++i) {
std::vector<MSTensor> pred;
std::string file2_path = browsed_news_path + "/00_user_id_data";
auto uid_file = file2_path + "/naml_browsed_news_" + std::to_string(i) + ".bin";
auto uid_nid = ReadFileToTensor(uid_file);
auto uid_nid_addr = reinterpret_cast<uint32_t *>(uid_nid.MutableData());
if (user_dict.find(uid_nid_addr[0]) == user_dict.end()) {
int rst = WriteResult(uid_file, pred);
if (rst != 0) {
std::cout << "write result failed." << std::endl;
return;
}
continue;
}
MSTensor dot2 = user_dict.at(uid_nid_addr[0]);
auto candidate_nid_file = file1_path + "/naml_browsed_news_" + std::to_string(i) + ".bin";
auto candidate_nid = ReadFileToTensor(candidate_nid_file);
size_t bin_size = candidate_nid.DataSize();
size_t browsed_news_count = bin_size / sizeof(float);
auto candidate_nid_addr = reinterpret_cast<uint32_t *>(candidate_nid.MutableData());
MSTensor ret("", mindspore::DataType::kNumberTypeFloat32, {static_cast<int>(browsed_news_count)},
nullptr, bin_size);
uint8_t *addr = reinterpret_cast<uint8_t *>(ret.MutableData());
for (size_t j = 0; j < browsed_news_count; ++j) {
float sum = 0;
if (news_dict.find(candidate_nid_addr[j]) == news_dict.end()) {
addr += sizeof(float);
continue;
}
MSTensor dot1 = news_dict.at(candidate_nid_addr[j]);
auto dot1_addr = reinterpret_cast<float *>(dot1.MutableData());
auto dot2_addr = reinterpret_cast<float *>(dot2.MutableData());
for (int k = 0; k < 400; ++k) {
sum = sum + dot1_addr[k] * dot2_addr[k];
}
memcpy(addr, &sum, sizeof(float));
addr += sizeof(float);
}
pred.emplace_back(ret);
int rst = WriteResult(uid_file, pred);
if (rst != 0) {
std::cout << "write result failed." << std::endl;
return;
}
}
std::cout << "=========InitPred end" << std::endl;
return;
}
int main(int argc, char **argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (RealPath(FLAGS_news_mindir).empty()) {
std::cout << "Invalid mindir" << std::endl;
return 1;
}
auto ascend310 = std::make_shared<mindspore::Ascend310DeviceInfo>();
ascend310->SetDeviceID(FLAGS_device_id);
context->MutableDeviceInfo().push_back(ascend310);
double startTimeMs;
double endTimeMs;
std::map<double, double> total_cost_time;
// om -> model
Model model0;
Model model1;
if (InitModel(FLAGS_news_mindir, &model0) != 0 || InitModel(FLAGS_user_mindir, &model1) != 0) {
std::cout << "ERROR: Init model failed." << std::endl;
return 1;
}
// get model inputs
std::vector<MSTensor> model0_inputs = model0.GetInputs();
if (model0_inputs.empty()) {
std::cout << "Invalid model, inputs is empty." << std::endl;
return 1;
}
// get input files by bin files
std::string news_dataset_path = FLAGS_base_path + "/news_test_data";
std::string history_data_path = FLAGS_base_path + "/users_test_data/01_history_data";
news_input0_0_files = GetAllFiles(news_dataset_path + "/00_category_data");
auto history_input_files = GetAllFiles(history_data_path);
if (news_input0_0_files.empty() || history_input_files.empty()) {
std::cout << "ERROR: input data empty." << std::endl;
return 1;
}
std::map<uint32_t, MSTensor> news_dict;
std::map<uint32_t, MSTensor> user_dict;
InitNewsDict(news_input0_0_files, model0_inputs, &news_dict, &model0);
InitUserDict(history_input_files, news_dict, &user_dict, &model1);
InitPred(news_dict, user_dict);
gettimeofday(&total_end, nullptr);
startTimeMs = (1.0 * total_start.tv_sec * 1000000 + total_start.tv_usec) / 1000;
endTimeMs = (1.0 * total_end.tv_sec * 1000000 + total_end.tv_usec) / 1000;
total_cost_time.insert(std::pair<double, double>(startTimeMs, endTimeMs));
double average0 = 0.0;
int inferCount0 = 0;
double average1 = 0.0;
int infer_cnt = 0;
GetAveTime(model0_cost_time, &inferCount0, &average0);
GetAveTime(model1_cost_time, &infer_cnt, &average1);
double total_time = total_cost_time.begin()->second - total_cost_time.begin()->first;
std::stringstream timeCost0, timeCost1, totalTimeCost;
timeCost0 << "first model cost average time: "<< average0 << " ms of infer_count " << inferCount0 << std::endl;
timeCost1 << "second model cost average time: "<< average1 << " ms of infer_count " << infer_cnt << std::endl;
totalTimeCost << "total cost time: "<< total_time << " ms of infer_count " << infer_cnt << std::endl;
std::string fileName = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream fileStream(fileName.c_str(), std::ios::trunc);
fileStream << timeCost0.str() << std::endl;
fileStream << timeCost1.str() << std::endl;
fileStream << totalTimeCost.str() << std::endl;
std::cout << timeCost0.str() << std::endl;
std::cout << timeCost1.str() << std::endl;
std::cout << totalTimeCost.str() << std::endl;
fileStream.close();
model0_cost_time.clear();
model1_cost_time.clear();
total_cost_time.clear();
std::cout << "Execute success." << std::endl;
return 0;
}
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gflags/gflags.h>
#include <string>
#include <iostream>
#include <memory>
#include <fstream>
#include "../inc/utils.h"
#include "../inc/sample_process.h"
bool g_isDevice = false;
DEFINE_string(news_om_path, "../model/relu_double_geir.om", "om model path.");
DEFINE_string(user_om_path, "../model/relu_double_geir.om", "om model path.");
DEFINE_string(news_dataset_path, "../data", "input data dir");
DEFINE_string(user_dataset_path, "../data", "input data dir");
DEFINE_string(newsid_data_path, "../data", "input data dir");
DEFINE_string(userid_data_path, "../data", "input data dir");
DEFINE_string(browsed_news_path, "../data", "input data dir");
DEFINE_int32(batch_size, 16, "batch size");
DEFINE_int32(device_id, 0, "device id");
DEFINE_int32(thread_num, 8, "thread num");
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "news OM File Path :" << FLAGS_news_om_path << std::endl;
std::cout << "user OM File Path :" << FLAGS_user_om_path << std::endl;
std::cout << "news Dataset Path :" << FLAGS_news_dataset_path << std::endl;
std::cout << "user Dataset Path :" << FLAGS_user_dataset_path << std::endl;
std::cout << "browsed_news_path Path :" << FLAGS_browsed_news_path << std::endl;
std::cout << "batch size :" << FLAGS_batch_size << std::endl;
std::cout << "device id :" << FLAGS_device_id << std::endl;
std::cout << "thread num :" << FLAGS_thread_num << std::endl;
std::vector<std::string> omPaths;
std::vector<std::string> datasetPaths;
std::vector<std::string> idsPaths;
omPaths.emplace_back(FLAGS_news_om_path);
omPaths.emplace_back(FLAGS_user_om_path);
datasetPaths.emplace_back(FLAGS_news_dataset_path);
datasetPaths.emplace_back(FLAGS_user_dataset_path);
idsPaths.emplace_back(FLAGS_newsid_data_path);
idsPaths.emplace_back(FLAGS_userid_data_path);
SampleProcess processSample(FLAGS_device_id, FLAGS_thread_num);
Result ret = processSample.InitResource();
if (ret != SUCCESS) {
ERROR_LOG("sample init resource failed");
return FAILED;
}
ret = processSample.Process(omPaths, datasetPaths, idsPaths, FLAGS_browsed_news_path, FLAGS_batch_size);
if (ret != SUCCESS) {
ERROR_LOG("sample process failed");
return FAILED;
}
std::vector<std::string> costTime = processSample.GetModelExecCostTimeInfo();
std::string file_name = "./time_Result" + std::string("/test_perform_static.txt");
std::ofstream file_stream(file_name.c_str(), std::ios::trunc);
for (auto cost : costTime) {
std::cout << cost << std::endl;
file_stream << cost << std::endl;
}
file_stream.close();
INFO_LOG("execute sample success");
return SUCCESS;
}
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/time.h>
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <algorithm>
#include "../inc/utils.h"
#include "../inc/model_process.h"
extern bool g_isDevice;
ModelProcess::ModelProcess(const std::string &inputDataPath, const std::string &idFilePath, uint32_t batchSize):
modelId_(0),
modelMemSize_(0),
modelWeightSize_(0),
modelMemPtr_(nullptr),
modelWeightPtr_(nullptr),
loadFlag_(false),
modelDesc_(nullptr),
output_(nullptr),
inputDataPath_(inputDataPath),
input_(nullptr),
batchSize_(batchSize),
idFilePath_(idFilePath),
inputNum_(0),
outputNum_(0) {}
ModelProcess::~ModelProcess() {
Unload();
DestroyResource();
}
Result ModelProcess::InitResource() {
Result ret = CreateDesc();
if (ret != SUCCESS) {
ERROR_LOG("create model description failed");
return FAILED;
}
ret = CreateOutput();
if (ret != SUCCESS) {
ERROR_LOG("create model output failed");
return FAILED;
}
ret = CreateInput();
if (ret != SUCCESS) {
ERROR_LOG("create model input failed");
return FAILED;
}
ret = ReadIdFiles();
if (ret != SUCCESS) {
ERROR_LOG("read id files failed");
return FAILED;
}
}
void ModelProcess::DestroyResource() {
DestroyDesc();
DestroyInput();
DestroyOutput();
return;
}
Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) {
if (loadFlag_) {
ERROR_LOG("has already loaded a model");
return FAILED;
}
aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("query model failed, model file is %s", modelPath);
return FAILED;
}
ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_);
return FAILED;
}
ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_);
return FAILED;
}
ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_,
modelMemSize_, modelWeightPtr_, modelWeightSize_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("load model from file failed, model file is %s", modelPath);
return FAILED;
}
loadFlag_ = true;
INFO_LOG("load model %s success", modelPath);
return SUCCESS;
}
Result ModelProcess::CreateDesc() {
modelDesc_ = aclmdlCreateDesc();
if (modelDesc_ == nullptr) {
ERROR_LOG("create model description failed");
return FAILED;
}
aclError ret = aclmdlGetDesc(modelDesc_, modelId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("get model description failed");
return FAILED;
}
INFO_LOG("create model description success");
return SUCCESS;
}
void ModelProcess::DestroyDesc() {
if (modelDesc_ != nullptr) {
(void)aclmdlDestroyDesc(modelDesc_);
modelDesc_ = nullptr;
}
}
Result ModelProcess::CreateInput() {
if (modelDesc_ == nullptr) {
ERROR_LOG("no model description, create output failed");
return FAILED;
}
input_ = aclmdlCreateDataset();
if (input_ == nullptr) {
ERROR_LOG("can't create dataset, create input failed");
return FAILED;
}
size_t inputSize = aclmdlGetNumInputs(modelDesc_);
inputNum_ = inputSize;
for (size_t i = 0; i < inputSize; ++i) {
size_t buffer_size = aclmdlGetInputSizeByIndex(modelDesc_, i);
inputBuffSize_.emplace_back(buffer_size);
void *inputBuffer = nullptr;
aclError ret = aclrtMalloc(&inputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't malloc buffer, size is %zu, create input failed", buffer_size);
return FAILED;
}
aclDataBuffer* inputData = aclCreateDataBuffer(inputBuffer, buffer_size);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't create data buffer, create input failed");
aclrtFree(inputBuffer);
return FAILED;
}
ret = aclmdlAddDatasetBuffer(input_, inputData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't add data buffer, create output failed");
aclrtFree(inputBuffer);
aclDestroyDataBuffer(inputData);
return FAILED;
}
}
INFO_LOG("create model input success");
return SUCCESS;
}
void ModelProcess::DestroyInput() {
if (input_ == nullptr) {
return;
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i);
aclDestroyDataBuffer(dataBuffer);
}
aclmdlDestroyDataset(input_);
input_ = nullptr;
}
Result ModelProcess::CreateOutput() {
if (modelDesc_ == nullptr) {
ERROR_LOG("no model description, create output failed");
return FAILED;
}
output_ = aclmdlCreateDataset();
if (output_ == nullptr) {
ERROR_LOG("can't create dataset, create output failed");
return FAILED;
}
size_t outputSize = aclmdlGetNumOutputs(modelDesc_);
outputNum_ = outputSize;
for (size_t i = 0; i < outputSize; ++i) {
size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i);
outputBuffSize_.emplace_back(buffer_size);
void *outputBuffer = nullptr;
aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size);
return FAILED;
}
aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't create data buffer, create output failed");
aclrtFree(outputBuffer);
return FAILED;
}
ret = aclmdlAddDatasetBuffer(output_, outputData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("can't add data buffer, create output failed");
aclrtFree(outputBuffer);
aclDestroyDataBuffer(outputData);
return FAILED;
}
}
INFO_LOG("create model output success");
return SUCCESS;
}
void ModelProcess::OutputModelResult() {
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
uint32_t len = aclGetDataBufferSizeV2(dataBuffer);
void *outHostData = NULL;
aclError ret = ACL_ERROR_NONE;
float *outData = NULL;
if (!g_isDevice) {
ret = aclrtMallocHost(&outHostData, len);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
return;
}
ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret);
(void)aclrtFreeHost(outHostData);
return;
}
outData = reinterpret_cast<float *>(outHostData);
} else {
outData = reinterpret_cast<float *>(data);
}
std::map<float, unsigned int, std::greater<float> > resultMap;
for (unsigned int j = 0; j < len / sizeof(float); ++j) {
resultMap[*outData] = j;
outData++;
}
int cnt = 0;
for (auto it = resultMap.begin(); it != resultMap.end(); ++it) {
// print top 5
if (++cnt > 5) {
break;
}
INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first);
}
if (!g_isDevice) {
ret = aclrtFreeHost(outHostData);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret);
return;
}
}
}
INFO_LOG("output data success");
return;
}
void ModelProcess::DestroyOutput() {
if (output_ == nullptr) {
return;
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
(void)aclrtFree(data);
(void)aclDestroyDataBuffer(dataBuffer);
}
(void)aclmdlDestroyDataset(output_);
output_ = nullptr;
}
Result ModelProcess::CpyFileToDevice(std::string fileName, uint32_t inputNum) {
uint32_t inputHostBuffSize = 0;
void *inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize);
if (inputHostBuff == nullptr) {
return FAILED;
}
aclDataBuffer *inBufferDev = aclmdlGetDatasetBuffer(input_, inputNum);
void *p_batchDst = aclGetDataBufferAddr(inBufferDev);
aclrtMemset(p_batchDst, inputHostBuffSize, 0, inputHostBuffSize);
aclError ret = aclrtMemcpy(p_batchDst, inputHostBuffSize, inputHostBuff, inputHostBuffSize,
ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u",
inputHostBuffSize, inputHostBuffSize);
aclrtFreeHost(inputHostBuff);
return FAILED;
}
aclrtFreeHost(inputHostBuff);
return SUCCESS;
}
Result ModelProcess::CpyDataToDevice(void *data, uint32_t len, uint32_t inputNum) {
if (len != inputBuffSize_[inputNum]) {
return FAILED;
}
aclDataBuffer *inBufferDev = aclmdlGetDatasetBuffer(input_, inputNum);
void *p_batchDst = aclGetDataBufferAddr(inBufferDev);
aclrtMemset(p_batchDst, len, 0, len);
aclError ret = aclrtMemcpy(p_batchDst, len, data, len, ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u",
len, len);
return FAILED;
}
return SUCCESS;
}
void ModelProcess::CpyOutputFromDeviceToHost(uint32_t index) {
size_t outputNum = aclmdlGetDatasetNumBuffers(output_);
for (size_t i = 0; i < outputNum; ++i) {
aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i);
void* data = aclGetDataBufferAddr(dataBuffer);
uint32_t bufferSize = aclGetDataBufferSizeV2(dataBuffer);
void* outHostData = NULL;
aclError ret = ACL_ERROR_NONE;
ret = aclrtMallocHost(&outHostData, bufferSize);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret);
return;
}
ret = aclrtMemcpy(outHostData, bufferSize, data, bufferSize, ACL_MEMCPY_DEVICE_TO_HOST);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret);
(void)aclrtFreeHost(outHostData);
return;
}
uint32_t len = (uint32_t)bufferSize / batchSize_;
for (size_t j = 0; j < batchSize_; j++) {
result_.emplace(ids_[index][j], reinterpret_cast<uint8_t *>(outHostData) + (j * len));
}
}
return;
}
std::vector<std::vector<void *>> ModelProcess::ReadInputFiles(std::vector<std::vector<std::string>> inputFiles,
size_t inputSize,
std::vector<std::vector<uint32_t>> *fileSize) {
size_t fileNum = inputFiles[0].size();
std::vector<std::vector<void *>> buff(fileNum);
if (inputFiles.size() != inputSize) {
std::cout << "the num of input file is incorrect" << std::endl;
return buff;
}
void *inputHostBuff = nullptr;
uint32_t inputHostBuffSize = 0;
for (int i = 0; i < inputSize; ++i) {
for (int j = 0; j < fileNum; ++j) {
inputHostBuff = Utils::ReadBinFile(inputFiles[i][j], &inputHostBuffSize);
buff[i].emplace_back(inputHostBuff);
(*fileSize)[i].emplace_back(inputHostBuffSize);
}
}
return buff;
}
Result ModelProcess::ReadIdFiles() {
std::vector<std::string> idFiles = Utils::GetAllBins(idFilePath_);
for (int i = 0; i < idFiles.size(); ++i) {
std::vector<int> ids;
Utils::ReadFileToVector(idFiles[i], batchSize_, &ids);
ids_.emplace_back(ids);
}
return SUCCESS;
}
uint32_t ModelProcess::ReadFiles() {
size_t inputSize = aclmdlGetNumInputs(modelDesc_);
std::vector<std::vector<uint32_t>> fileSize(inputSize);
std::vector<std::vector<std::string>> inputFiles = Utils::GetAllInputData(inputDataPath_);
fileBuff_ = ReadInputFiles(inputFiles, inputSize, &fileSize);
uint32_t fileNum = inputFiles[0].size();
fileSize_ = fileSize;
return fileNum;
}
Result ModelProcess::ExecuteWithFile(uint32_t fileNum) {
for (size_t index = 0; index < fileNum; ++index) {
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
gettimeofday(&start, NULL);
void *picDevBuffer = nullptr;
for (auto i = 0; i < inputNum_; ++i) {
CpyDataToDevice(fileBuff_[i][index], fileSize_[i][index], i);
}
aclError ret = aclmdlExecute(modelId_, input_, output_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("execute model failed, modelId is %u", modelId_);
return FAILED;
}
CpyOutputFromDeviceToHost(index);
gettimeofday(&end, NULL);
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map_.insert(std::pair<double, double>(startTime_ms, endTime_ms));
}
return SUCCESS;
}
Result ModelProcess::Execute(uint32_t index) {
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
gettimeofday(&start, NULL);
aclError ret = aclmdlExecute(modelId_, input_, output_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("execute model failed, modelId is %u", modelId_);
return FAILED;
}
CpyOutputFromDeviceToHost(index);
gettimeofday(&end, NULL);
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
costTime_map_.insert(std::pair<double, double>(startTime_ms, endTime_ms));
return SUCCESS;
}
std::map<int, void *> ModelProcess::GetResult() {
return result_;
}
void ModelProcess::Unload() {
if (!loadFlag_) {
WARN_LOG("no model had been loaded, unload failed");
return;
}
aclError ret = aclmdlUnload(modelId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("unload model failed, modelId is %u", modelId_);
}
if (modelDesc_ != nullptr) {
(void)aclmdlDestroyDesc(modelDesc_);
modelDesc_ = nullptr;
}
if (modelMemPtr_ != nullptr) {
aclrtFree(modelMemPtr_);
modelMemPtr_ = nullptr;
modelMemSize_ = 0;
}
if (modelWeightPtr_ != nullptr) {
aclrtFree(modelWeightPtr_);
modelWeightPtr_ = nullptr;
modelWeightSize_ = 0;
}
loadFlag_ = false;
INFO_LOG("unload model success, modelId is %u", modelId_);
}
std::vector<uint32_t> ModelProcess::GetInputSize() {
return inputBuffSize_;
}
std::vector<uint32_t> ModelProcess::GetOutputSize() {
return outputBuffSize_;
}
std::string ModelProcess::GetInputDataPath() {
return inputDataPath_;
}
std::string ModelProcess::GetCostTimeInfo() {
double average = 0.0;
int infer_cnt = 0;
for (auto iter = costTime_map_.begin(); iter != costTime_map_.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
average += diff;
infer_cnt++;
}
average = average / infer_cnt;
std::stringstream timeCost;
timeCost << "first model latency "<< average << " ms; count " << infer_cnt << std::endl;
return timeCost.str();
}
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <unordered_map>
#include <iterator>
#include <thread>
#include <sstream>
#include "acl/acl.h"
#include "../inc/utils.h"
#include "../inc/model_process.h"
#include "../inc/sample_process.h"
extern bool g_isDevice;
SampleProcess::SampleProcess() :deviceId_(0), context_(nullptr), stream_(nullptr), threadNum_(0) {}
SampleProcess::SampleProcess(uint32_t deviceId, uint32_t threadNum):
deviceId_(deviceId),
threadNum_(threadNum),
context_(nullptr),
stream_(nullptr) {}
SampleProcess::~SampleProcess() {
DestroyResource();
}
Result SampleProcess::InitResource() {
aclError ret = aclInit(nullptr);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl init failed");
return FAILED;
}
INFO_LOG("acl init success");
ret = aclrtSetDevice(deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl open device %d failed", deviceId_);
return FAILED;
}
INFO_LOG("open device %d success", deviceId_);
// create context (set current)
ret = aclrtCreateContext(&context_, deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl create context failed");
return FAILED;
}
INFO_LOG("create context success");
// create stream
ret = aclrtCreateStream(&stream_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl create stream failed");
return FAILED;
}
INFO_LOG("create stream success");
// get run mode
aclrtRunMode runMode;
ret = aclrtGetRunMode(&runMode);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("acl get run mode failed");
return FAILED;
}
g_isDevice = (runMode == ACL_DEVICE);
INFO_LOG("get run mode success");
return SUCCESS;
}
Result SampleProcess::CreateModelProcessInstance(const std::vector<std::string> &omPaths,
const std::vector<std::string> &inputDataPaths,
const std::vector<std::string> &inputIdPaths,
uint32_t batchSize,
std::map<int, std::shared_ptr<ModelProcess>> *modelProcessContainer) {
for (int i = 0; i < omPaths.size(); ++i) {
std::cout << "om_path : " << omPaths[i] << std::endl;
auto processModel = std::make_shared<ModelProcess>(inputDataPaths[i], inputIdPaths[i], batchSize);
Result ret = processModel->LoadModelFromFileWithMem(omPaths[i].c_str());
if (ret != SUCCESS) {
ERROR_LOG("load model from file failed");
return FAILED;
}
ret = processModel->InitResource();
if (ret != SUCCESS) {
ERROR_LOG("create model description failed");
return FAILED;
}
modelProcessContainer->emplace(i, processModel);
}
return SUCCESS;
}
std::vector<std::vector<std::vector<int>>> SampleProcess::ReadHistory(std::vector<std::string> historyFile,
uint32_t batchSize) {
std::vector<std::vector<std::vector<int>>> allHistory;
for (auto &file : historyFile) {
std::vector<std::vector<int>> history(batchSize, std::vector<int>(50));
Utils::ReadFileToVector(file, batchSize, 50, &history);
allHistory.emplace_back(history);
}
return allHistory;
}
Result SampleProcess::Process(const std::vector<std::string> &omPaths,
const std::vector<std::string> &inputDataPaths,
const std::vector<std::string> &inputIdPaths,
const std::string &browsedNewsPath,
uint32_t batchSize) {
INFO_LOG("Start do sample process");
struct timeval totalStart;
struct timeval totalEnd;
std::map<int, std::shared_ptr<ModelProcess>> modelProcessContainer;
CreateModelProcessInstance(omPaths, inputDataPaths, inputIdPaths, batchSize, &modelProcessContainer);
uint32_t fileNum = modelProcessContainer[0]->ReadFiles();
std::string historyDir = modelProcessContainer[1]->GetInputDataPath() + "/00_history_data";
std::vector<std::string> historyFile = Utils::GetAllBins(historyDir);
size_t historySize = historyFile.size();
std::vector<std::vector<std::vector<int>>> allHistory = ReadHistory(historyFile, batchSize);
uint32_t browsedFileNum = ReadBrowsedData(browsedNewsPath);
gettimeofday(&totalStart, NULL);
modelProcessContainer[0]->ExecuteWithFile(fileNum);
std::map<int, void *> result = modelProcessContainer[0]->GetResult();
std::vector<uint32_t> model1OutputBuffSize = modelProcessContainer[0]->GetOutputSize();
std::vector<uint32_t> inputBuffSize = modelProcessContainer[1]->GetInputSize();
uint32_t singleDatsSize = model1OutputBuffSize[0] / batchSize;
void* browedNews = NULL;
aclrtMallocHost(&browedNews, inputBuffSize[0]);
struct timeval start;
struct timeval end;
double startTime_ms;
double endTime_ms;
for (int i = 0; i < historySize; ++i) {
gettimeofday(&start, NULL);
for (int j = 0; j < 16; ++j) {
for (int k = 0; k < 50; ++k) {
auto it = result.find(allHistory[i][j][k]);
if (it != result.end()) {
aclrtMemcpy(reinterpret_cast<uint8_t *>(browedNews) + (j * 50 + k) * singleDatsSize, singleDatsSize,
result[allHistory[i][j][k]], singleDatsSize, ACL_MEMCPY_HOST_TO_HOST);
}
}
}
modelProcessContainer[1]->CpyDataToDevice(browedNews, inputBuffSize[0], 0);
modelProcessContainer[1]->Execute(i);
gettimeofday(&end, NULL);
startTime_ms = (1.0 * start.tv_sec * 1000000 + start.tv_usec) / 1000;
endTime_ms = (1.0 * end.tv_sec * 1000000 + end.tv_usec) / 1000;
secondModelCostTime_map_.insert(std::pair<double, double>(startTime_ms, endTime_ms));
}
GetPred(&modelProcessContainer, browsedFileNum);
gettimeofday(&totalEnd, NULL);
startTime_ms = (1.0 * totalStart.tv_sec * 1000000 + totalStart.tv_usec) / 1000;
endTime_ms = (1.0 * totalEnd.tv_sec * 1000000 + totalEnd.tv_usec) / 1000;
totalCostTime_map_.insert(std::pair<double, double>(startTime_ms, endTime_ms));
time_cost_.clear();
time_cost_.emplace_back(modelProcessContainer[0]->GetCostTimeInfo());
aclrtFreeHost(browedNews);
return SUCCESS;
}
Result SampleProcess::ReadBrowsedFile(const std::string &browsedNewsPath,
std::vector<std::string> userIdFiles,
std::vector<std::vector<int>> *usersIds,
std::vector<std::vector<int>> *candidateNewsIds) {
std::vector<int> candidateNewsId;
std::vector<int> usersId;
for (auto file : userIdFiles) {
candidateNewsId.clear();
usersId.clear();
std::size_t pos = file.rfind("/");
std::string name = file.substr(pos);
std::string newsIdFileName = browsedNewsPath + "/01_candidate_nid_data" + name;
Utils::ReadFileToVector(file, &usersId);
Utils::ReadFileToVector(newsIdFileName, &candidateNewsId);
usersIds->emplace_back(usersId);
candidateNewsIds->emplace_back(candidateNewsId);
}
return SUCCESS;
}
uint32_t SampleProcess::ReadBrowsedData(const std::string &browsedNewsPath) {
userIdFiles_ = Utils::GetAllBins(browsedNewsPath + "/00_user_id_data");
ReadBrowsedFile(browsedNewsPath, userIdFiles_, &usersIds_, &candidateNewsIds_);
uint32_t fileNum = userIdFiles_.size();
return fileNum;
}
Result SampleProcess::GetPred(std::map<int, std::shared_ptr<ModelProcess>> *modelProcessContainer,
uint32_t fileNum) {
std::map<int, void *> newsEncodeResult = (*modelProcessContainer)[0]->GetResult();
std::map<int, void *> userEncodeResult = (*modelProcessContainer)[1]->GetResult();
uint32_t perThreadNum = fileNum / threadNum_;
std::vector<std::thread> threads;
for (int i = 0; i < threadNum_; ++i) {
if (i != threadNum_ - 1) {
threads.emplace_back(std::thread(&SampleProcess::GetResult, this,
i * perThreadNum, (i + 1) * perThreadNum,
newsEncodeResult,
userEncodeResult));
} else {
threads.emplace_back(std::thread(&SampleProcess::GetResult, this,
i * perThreadNum,
fileNum,
newsEncodeResult,
userEncodeResult));
}
}
for (int i = 0; i < threads.size(); ++i) {
threads[i].join();
}
return SUCCESS;
}
void SampleProcess::GetResult(uint32_t startPos, uint32_t endPos,
std::map<int, void *> newsEncodeResult,
std::map<int, void *> userEncodeResult) {
for (int i = startPos; i < endPos; ++i) {
std::vector<std::vector<float>> newsCandidate;
std::vector<float> userEncodeIds(400);
for (int j = 0; j < candidateNewsIds_[i].size(); ++j) {
std::vector<float> newsResults(400);
float *newsResult = reinterpret_cast<float *>(newsEncodeResult[candidateNewsIds_[i][j]]);
std::copy(newsResult, newsResult + 400, newsResults.begin());
newsCandidate.emplace_back(newsResults);
}
float *userResult = reinterpret_cast<float *>(userEncodeResult[usersIds_[i][0]]);
std::copy(userResult, userResult + 400, userEncodeIds.begin());
std::vector<float> predResult;
for (int j = 0; j < newsCandidate.size(); ++j) {
float dotMulResult = 0;
for (int k = 0; k < 400; ++k) {
dotMulResult += newsCandidate[j][k] * userEncodeIds[k];
}
predResult.emplace_back(dotMulResult);
}
mtx_.lock();
WriteResult(userIdFiles_[i], predResult, predResult.size() * 4);
mtx_.unlock();
}
return;
}
int SampleProcess::WriteResult(const std::string& imageFile, std::vector<float> result, uint32_t size) {
std::string homePath = "./result_Files/";
std::size_t pos = imageFile.rfind("/");
std::string name = imageFile.substr(pos);
for (size_t i = 0; i < 1; ++i) {
std::string outFileName = homePath + "/" + name;
try {
FILE *outputFile = fopen(outFileName.c_str(), "wb");
fwrite(static_cast<void *>(&result[0]), size, sizeof(char), outputFile);
fclose(outputFile);
outputFile = nullptr;
} catch (std::exception &e) {
std::cout << "write result file " << outFileName << " failed, error info: " << e.what() << std::endl;
return FAILED;
}
}
return SUCCESS;
}
void SampleProcess::DestroyResource() {
aclError ret;
if (stream_ != nullptr) {
ret = aclrtDestroyStream(stream_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("destroy stream failed");
}
stream_ = nullptr;
}
INFO_LOG("end to destroy stream");
if (context_ != nullptr) {
ret = aclrtDestroyContext(context_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("destroy context failed");
}
context_ = nullptr;
}
INFO_LOG("end to destroy context");
ret = aclFinalize();
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("finalize acl failed");
}
INFO_LOG("end to finalize acl");
ret = aclrtResetDevice(deviceId_);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("reset device failed");
}
INFO_LOG("end to reset device is %d", deviceId_);
}
std::vector<std::string> SampleProcess::GetModelExecCostTimeInfo() {
double secondModelAverage = 0.0;
int infer_cnt = 0;
for (auto iter = secondModelCostTime_map_.begin(); iter != secondModelCostTime_map_.end(); iter++) {
double diff = 0.0;
diff = iter->second - iter->first;
secondModelAverage += diff;
infer_cnt++;
}
secondModelAverage = secondModelAverage / infer_cnt;
std::stringstream timeCost;
timeCost << "second model inference cost average time: "<< secondModelAverage <<
" ms of infer_count " << infer_cnt << std::endl;
time_cost_.emplace_back(timeCost.str());
double totalCostTime = totalCostTime_map_.begin()->second - totalCostTime_map_.begin()->first;
std::stringstream totalTimeCost;
totalTimeCost << "total inference cost time: "<< totalCostTime << " ms; count " << infer_cnt << std::endl;
time_cost_.emplace_back(totalTimeCost.str());
return time_cost_;
}
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <algorithm>
#include <iostream>
#include "inc/utils.h"
using mindspore::MSTensor;
using mindspore::DataType;
std::vector<std::string> GetAllFiles(std::string_view dirName) {
struct dirent *filename;
DIR *dir = OpenDir(dirName);
if (dir == nullptr) {
return {};
}
std::vector<std::string> res;
while ((filename = readdir(dir)) != nullptr) {
std::string dName = std::string(filename->d_name);
if (dName == "." || dName == ".." || filename->d_type != DT_REG) {
continue;
}
res.emplace_back(std::string(dirName) + "/" + filename->d_name);
}
std::sort(res.begin(), res.end());
for (auto &f : res) {
std::cout << "image file: " << f << std::endl;
}
return res;
}
int WriteResult(const std::string& imageFile, const std::vector<MSTensor> &outputs) {
std::string homePath = "./result_Files";
const int INVALID_POINTER = -1;
const int ERROR = -2;
for (size_t i = 0; i < outputs.size(); ++i) {
size_t outputSize;
std::shared_ptr<const void> netOutput;
netOutput = outputs[i].Data();
outputSize = outputs[i].DataSize();
int pos = imageFile.rfind('/');
std::string fileName(imageFile, pos + 1);
fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), '_' + std::to_string(i) + ".bin");
std::string outFileName = homePath + "/" + fileName;
FILE * outputFile = fopen(outFileName.c_str(), "wb");
if (outputFile == nullptr) {
std::cout << "open result file " << outFileName << " failed" << std::endl;
return INVALID_POINTER;
}
size_t size = fwrite(netOutput.get(), sizeof(char), outputSize, outputFile);
if (size != outputSize) {
fclose(outputFile);
outputFile = nullptr;
std::cout << "write result file " << outFileName << " failed, write size[" << size <<
"] is smaller than output size[" << outputSize << "], maybe the disk is full." << std::endl;
return ERROR;
}
fclose(outputFile);
outputFile = nullptr;
}
return 0;
}
mindspore::MSTensor ReadFileToTensor(const std::string &file) {
if (file.empty()) {
std::cout << "Pointer file is nullptr" << std::endl;
return mindspore::MSTensor();
}
std::ifstream ifs(file);
if (!ifs.good()) {
std::cout << "File: " << file << " is not exist" << std::endl;
return mindspore::MSTensor();
}
if (!ifs.is_open()) {
std::cout << "File: " << file << "open failed" << std::endl;
return mindspore::MSTensor();
}
ifs.seekg(0, std::ios::end);
size_t size = ifs.tellg();
mindspore::MSTensor buffer(file, mindspore::DataType::kNumberTypeUInt8, {static_cast<int64_t>(size)}, nullptr, size);
ifs.seekg(0, std::ios::beg);
ifs.read(reinterpret_cast<char *>(buffer.MutableData()), size);
ifs.close();
return buffer;
}
DIR *OpenDir(std::string_view dirName) {
if (dirName.empty()) {
std::cout << " dirName is null ! " << std::endl;
return nullptr;
}
std::string realPath = RealPath(dirName);
struct stat s;
lstat(realPath.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
std::cout << "dirName is not a valid directory !" << std::endl;
return nullptr;
}
DIR *dir;
dir = opendir(realPath.c_str());
if (dir == nullptr) {
std::cout << "Can not open dir " << dirName << std::endl;
return nullptr;
}
std::cout << "Successfully opened the dir " << dirName << std::endl;
return dir;
}
std::string RealPath(std::string_view path) {
char realPathMem[PATH_MAX] = {0};
char *realPathRet = nullptr;
realPathRet = realpath(path.data(), realPathMem);
if (realPathRet == nullptr) {
std::cout << "File: " << path << " is not exist.";
return "";
}
std::string realPath(realPathMem);
std::cout << path << " realpath is: " << realPath << std::endl;
return realPath;
}
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/stat.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>
#include "acl/acl.h"
#include "../inc/utils.h"
extern bool g_isDevice;
void* Utils::ReadBinFile(std::string fileName, uint32_t *fileSize) {
struct stat sBuf;
int fileStatus = stat(fileName.data(), &sBuf);
if (fileStatus == -1) {
ERROR_LOG("failed to get file");
return nullptr;
}
if (S_ISREG(sBuf.st_mode) == 0) {
ERROR_LOG("%s is not a file, please enter a file", fileName.c_str());
return nullptr;
}
std::ifstream binFile(fileName, std::ifstream::binary);
if (binFile.is_open() == false) {
ERROR_LOG("open file %s failed", fileName.c_str());
return nullptr;
}
binFile.seekg(0, binFile.end);
uint32_t binFileBufferLen = binFile.tellg();
if (binFileBufferLen == 0) {
ERROR_LOG("binfile is empty, filename is %s", fileName.c_str());
binFile.close();
return nullptr;
}
binFile.seekg(0, binFile.beg);
void* binFileBufferData = nullptr;
if (!g_isDevice) {
aclrtMallocHost(&binFileBufferData, binFileBufferLen);
if (binFileBufferData == nullptr) {
ERROR_LOG("malloc binFileBufferData failed");
binFile.close();
return nullptr;
}
} else {
aclError ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen);
binFile.close();
return nullptr;
}
}
binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen);
binFile.close();
*fileSize = binFileBufferLen;
return binFileBufferData;
}
void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize) {
uint32_t inputHostBuffSize = 0;
void* inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize);
if (inputHostBuff == nullptr) {
return nullptr;
}
if (!g_isDevice) {
void *inBufferDev = nullptr;
uint32_t inBufferSize = inputHostBuffSize;
aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u",
inBufferSize, inputHostBuffSize);
aclrtFree(inBufferDev);
aclrtFreeHost(inputHostBuff);
return nullptr;
}
aclrtFreeHost(inputHostBuff);
*fileSize = inBufferSize;
return inBufferDev;
} else {
*fileSize = inputHostBuffSize;
return inputHostBuff;
}
}
std::vector<std::vector<std::string>> Utils::GetAllInputData(std::string dir_name) {
DIR *dir = OpenDir(dir_name);
if (dir == nullptr) {
return {};
}
struct dirent *filename;
std::vector<std::string> sub_dirs;
while ((filename = readdir(dir)) != nullptr) {
std::string d_name = std::string(filename->d_name);
if (d_name == "." || d_name == ".." || d_name.empty() || d_name[0] != '0') {
continue;
}
std::string dir_path = RealPath(std::string(dir_name) + "/" + filename->d_name);
struct stat s;
lstat(dir_path.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
continue;
}
sub_dirs.emplace_back(dir_path);
}
std::sort(sub_dirs.begin(), sub_dirs.end());
std::vector<std::vector<std::string>> result(sub_dirs.size());
std::transform(sub_dirs.begin(), sub_dirs.end(), result.begin(), GetAllBins);
return result;
}
DIR *Utils::OpenDir(std::string dir_name) {
// check the parameter !
if (dir_name.empty()) {
std::cout << " dir_name is null ! " << std::endl;
return nullptr;
}
std::string real_path = RealPath(dir_name);
// check if dir_name is a valid dir
struct stat s;
lstat(real_path.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
std::cout << "dir_name is not a valid directory !" << std::endl;
return nullptr;
}
DIR *dir = opendir(real_path.c_str());
if (dir == nullptr) {
std::cout << "Can not open dir " << dir_name << std::endl;
return nullptr;
}
std::cout << "Successfully opened the dir " << dir_name << std::endl;
return dir;
}
std::string Utils::RealPath(std::string path) {
char real_path_mem[PATH_MAX] = {0};
char *real_path_ret = nullptr;
real_path_ret = realpath(path.data(), real_path_mem);
if (real_path_ret == nullptr) {
std::cout << "File: " << path << " is not exist.";
return "";
}
std::string real_path(real_path_mem);
std::cout << path << " realpath is: " << real_path << std::endl;
return real_path;
}
std::vector<std::string> Utils::GetAllBins(std::string dir_name) {
struct dirent *filename;
DIR *dir = OpenDir(dir_name);
if (dir == nullptr) {
return {};
}
std::vector<std::string> res;
while ((filename = readdir(dir)) != nullptr) {
std::string d_name = std::string(filename->d_name);
if (d_name == "." || d_name == ".." || d_name.size() <= 3 || d_name.substr(d_name.size() - 4) != ".bin" ||
filename->d_type != DT_REG) {
continue;
}
res.emplace_back(std::string(dir_name) + "/" + filename->d_name);
}
std::sort(res.begin(), res.end());
return res;
}
Result Utils::ReadFileToVector(std::string newsIdFileName, std::vector<int> *newsId) {
int id;
std::ifstream in(newsIdFileName, std::ios::in | std::ios::binary);
while (in.read(reinterpret_cast<char *>(&id), sizeof(id))) {
newsId->emplace_back(id);
}
in.close();
return SUCCESS;
}
Result Utils::ReadFileToVector(std::string newsIdFileName, uint32_t batchSize, std::vector<int> *newsId) {
int id;
std::ifstream in(newsIdFileName, std::ios::in | std::ios::binary);
for (int i = 0; i < batchSize; ++i) {
in.read(reinterpret_cast<char *>(&id), sizeof(id));
newsId->emplace_back(id);
}
in.close();
return SUCCESS;
}
Result Utils::ReadFileToVector(std::string fileName, uint32_t batchSize,
uint32_t count, std::vector<std::vector<int>> *newsId) {
int id;
std::ifstream in(fileName, std::ios::in | std::ios::binary);
for (int i = 0; i < batchSize; ++i) {
for (int j = 0; j < count; ++j) {
in.read(reinterpret_cast<char *>(&id), sizeof(id));
(*newsId)[i][j] = id;
}
}
in.close();
return SUCCESS;
}
......@@ -15,16 +15,11 @@
"""Evaluation for NAML"""
import os
import argparse
from model_utils.config import config
import numpy as np
from sklearn.metrics import roc_auc_score
parser = argparse.ArgumentParser(description="")
parser.add_argument("--result_path", type=str, default="", help="Device id")
parser.add_argument("--label_path", type=str, default="", help="output file name.")
args = parser.parse_args()
def AUC(y_true, y_pred):
return roc_auc_score(y_true, y_pred)
......@@ -79,15 +74,23 @@ class NAMLMetric:
def get_metric(result_path, label_path, metric):
"""get accuracy"""
result_files = os.listdir(result_path)
for file in result_files:
result_file = os.path.join(result_path, file)
label_list = os.listdir(label_path)
for file in label_list:
f = file.split(".bin")[0] + "_0.bin"
result_file = os.path.join(result_path, f)
if not os.path.exists(result_file):
print("exclude file:", file)
continue
pred = np.fromfile(result_file, dtype=np.float32)
if pred.size == 0:
print("exclude file:", file)
continue
label_file = os.path.join(label_path, file)
label = np.fromfile(label_file, dtype=np.int32)
if np.nan in pred:
print("exclude file:", file)
continue
metric.update(pred, label)
......@@ -96,4 +99,4 @@ def get_metric(result_path, label_path, metric):
if __name__ == "__main__":
naml_metric = NAMLMetric()
get_metric(args.result_path, args.label_path, naml_metric)
get_metric(config.result_path, config.label_path, naml_metric)
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""Preprocess NAML."""
import os
from model_utils.config import config
from src.dataset import MINDPreprocess
from src.dataset import create_eval_dataset, EvalNews, EvalUsers, EvalCandidateNews
def export_bin():
'''pre process function.'''
config.phase = "eval"
config.neg_sample = config.eval_neg_sample
config.embedding_file = os.path.join(config.dataset_path, config.embedding_file)
config.word_dict_path = os.path.join(config.dataset_path, config.word_dict_path)
config.category_dict_path = os.path.join(config.dataset_path, config.category_dict_path)
config.subcategory_dict_path = os.path.join(config.dataset_path, config.subcategory_dict_path)
config.uid2index_path = os.path.join(config.dataset_path, config.uid2index_path)
config.train_dataset_path = os.path.join(config.dataset_path, config.train_dataset_path)
config.eval_dataset_path = os.path.join(config.dataset_path, config.eval_dataset_path)
args = config
mindpreprocess = MINDPreprocess(vars(args), dataset_path=args.eval_dataset_path)
base_path = args.preprocess_path
data_dir = base_path + '/news_test_data/'
news_id_folder = base_path + "/news_id_data/"
if not os.path.exists(news_id_folder):
os.makedirs(news_id_folder)
print("======== news_id_folder is ", news_id_folder, flush=True)
category_folder = os.path.join(data_dir, "00_category_data")
if not os.path.exists(category_folder):
os.makedirs(category_folder)
print("======== category_folder is ", category_folder, flush=True)
subcategory_folder = os.path.join(data_dir, "01_subcategory_data")
if not os.path.exists(subcategory_folder):
os.makedirs(subcategory_folder)
title_folder = os.path.join(data_dir, "02_title_data")
if not os.path.exists(title_folder):
os.makedirs(title_folder)
abstract_folder = os.path.join(data_dir, "03_abstract_data")
if not os.path.exists(abstract_folder):
os.makedirs(abstract_folder)
dataset = create_eval_dataset(mindpreprocess, EvalNews, batch_size=args.batch_size)
iterator = dataset.create_dict_iterator(output_numpy=True)
idx = 0
for idx, data in enumerate(iterator):
news_id = data["news_id"]
category = data["category"]
subcategory = data["subcategory"]
title = data["title"]
abstract = data["abstract"]
file_name = "naml_news_" + str(idx) + ".bin"
news_id_file_path = os.path.join(news_id_folder, file_name)
news_id.tofile(news_id_file_path)
category_file_path = os.path.join(category_folder, file_name)
category.tofile(category_file_path)
subcategory_file_path = os.path.join(subcategory_folder, file_name)
subcategory.tofile(subcategory_file_path)
title_file_path = os.path.join(title_folder, file_name)
title.tofile(title_file_path)
abstract_file_path = os.path.join(abstract_folder, file_name)
abstract.tofile(abstract_file_path)
data_dir = base_path + '/users_test_data/'
user_id_folder = os.path.join(data_dir, "00_user_id_data")
print("======== user_id_folder is ", user_id_folder)
if not os.path.exists(user_id_folder):
os.makedirs(user_id_folder)
history_folder = os.path.join(data_dir, "01_history_data")
if not os.path.exists(history_folder):
os.makedirs(history_folder)
dataset = create_eval_dataset(mindpreprocess, EvalUsers, batch_size=args.batch_size)
iterator = dataset.create_dict_iterator(output_numpy=True)
for idx, data in enumerate(iterator):
user_id = data["uid"]
history = data["history"]
file_name = "naml_users_" + str(idx) + ".bin"
user_id_file_path = os.path.join(user_id_folder, file_name)
user_id.tofile(user_id_file_path)
history_file_path = os.path.join(history_folder, file_name)
history.tofile(history_file_path)
data_dir = base_path + '/browsed_news_test_data/'
user_id_folder = os.path.join(data_dir, "00_user_id_data")
if not os.path.exists(user_id_folder):
os.makedirs(user_id_folder)
candidate_nid_folder = os.path.join(data_dir, "01_candidate_nid_data")
if not os.path.exists(candidate_nid_folder):
os.makedirs(candidate_nid_folder)
labels_folder = os.path.join(data_dir, "02_labels_data")
print("======== labels_folder is ", labels_folder)
if not os.path.exists(labels_folder):
os.makedirs(labels_folder)
dataset = create_eval_dataset(mindpreprocess, EvalCandidateNews, batch_size=args.batch_size)
iterator = dataset.create_dict_iterator(output_numpy=True)
for idx, data in enumerate(iterator):
# 'uid', 'candidate_nid', 'labels'
uid = data["uid"]
candidate_nid = data["candidate_nid"]
labels = data["labels"]
file_name = "naml_browsed_news_" + str(idx) + ".bin"
user_id_file_path = os.path.join(user_id_folder, file_name)
uid.tofile(user_id_file_path)
candidate_nid_file_path = os.path.join(candidate_nid_folder, file_name)
candidate_nid.tofile(candidate_nid_file_path)
labels_file_path = os.path.join(labels_folder, file_name)
labels.tofile(labels_file_path)
if __name__ == "__main__":
export_bin()
......@@ -14,8 +14,8 @@
# limitations under the License.
# ============================================================================
if [[ $# -lt 8 || $# -gt 9 ]]; then
echo "Usage: sh run_infer_310.sh [NEWS_MODEL] [USER_MODEL] [NEWS_DATASET_PATH] [USER_DATASET_PATH] [NEWS_ID_PATH] [USER_ID_PATH] [BROWSED_NEWS_PATH] [SOC_VERSION] [DEVICE_ID]
if [[ $# -lt 2 || $# -gt 3 ]]; then
echo "Usage: bash run_infer_310.sh [NEWS_MODEL] [USER_MODEL] [DEVICE_ID]
DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero"
exit 1
fi
......@@ -30,16 +30,10 @@ get_real_path(){
news_model=$(get_real_path $1)
user_model=$(get_real_path $2)
news_dataset_path=$(get_real_path $3)
user_dataset_path=$(get_real_path $4)
news_id_path=$(get_real_path $5)
user_id_path=$(get_real_path $6)
browsed_news_path=$(get_real_path $7)
soc_version=$8
if [ $# == 9 ]; then
device_id=$9
elif [ $# == 8 ]; then
if [ $# == 3 ]; then
device_id=$3
elif [ $# == 2 ]; then
if [ -z $device_id ]; then
device_id=0
else
......@@ -49,11 +43,6 @@ fi
echo $news_model
echo $user_model
echo $news_dataset_path
echo $news_id_path
echo $user_id_path
echo $browsed_news_path
echo $soc_version
echo $device_id
export ASCEND_HOME=/usr/local/Ascend/
......@@ -70,10 +59,17 @@ else
export ASCEND_OPP_PATH=$ASCEND_HOME/opp
fi
function air_to_om()
function preprocess_data()
{
atc --framework=1 --model=$news_model --output=news_encoder --soc_version=$soc_version
atc --framework=1 --model=$user_model --output=user_encoder --soc_version=$soc_version
if [ -d preprocess_Result ]; then
rm -rf ./preprocess_Result
fi
mkdir preprocess_Result
python3.7 ../preprocess.py --preprocess_path=./preprocess_Result &> preprocess.log
if [ $? -ne 0 ]; then
echo "preprocess data failed"
exit 1
fi
}
function compile_app()
......@@ -101,7 +97,7 @@ function infer()
fi
mkdir result_Files
mkdir time_Result
../ascend310_infer/out/main --news_om_path news_encoder.om --user_om_path user_encoder.om --news_dataset_path $news_dataset_path --user_dataset_path $user_dataset_path --newsid_data_path $news_id_path --userid_data_path $user_id_path --browsed_news_path $browsed_news_path &> infer.log
../ascend310_infer/out/main --news_mindir=$news_model --user_mindir=$user_model --device_id=$device_id --base_path=./preprocess_Result &> infer.log
if [ $? -ne 0 ]; then
echo "execute inference failed"
exit 1
......@@ -110,14 +106,14 @@ function infer()
function cal_acc()
{
python ../postprocess.py --result_path=./result_Files --label_path=$browsed_news_path/02_labels_data &> acc.log
python ../postprocess.py --result_path=./result_Files --label_path=./preprocess_Result/browsed_news_test_data/02_labels_data &> acc.log
if [ $? -ne 0 ]; then
echo "calculate accuracy failed"
exit 1
fi
}
air_to_om
preprocess_data
compile_app
infer
cal_acc
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment