diff --git a/research/cv/PDarts/infer/convert/air2om.sh b/research/cv/PDarts/infer/convert/air2om.sh new file mode 100644 index 0000000000000000000000000000000000000000..7d26c8629a54c7a820e3233cba4f2e62aeef0bc6 --- /dev/null +++ b/research/cv/PDarts/infer/convert/air2om.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# Copyright 2022 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. +model_path=$1 +output_path=$2 +atc --model=$model_path\ + --framework=1 \ + --output=$output_path \ + --input_format=NCHW \ + --soc_version=Ascend310 \ + --output_type=FP32 diff --git a/research/cv/PDarts/infer/data/config/pdarts.cfg b/research/cv/PDarts/infer/data/config/pdarts.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b18718a1da5891d2b8a4498b06638a2b4c7619a9 --- /dev/null +++ b/research/cv/PDarts/infer/data/config/pdarts.cfg @@ -0,0 +1,3 @@ +CLASS_NUM=10 +SOFTMAX=false +TOP_K=5 diff --git a/research/cv/PDarts/infer/data/config/pdarts.pipeline b/research/cv/PDarts/infer/data/config/pdarts.pipeline new file mode 100644 index 0000000000000000000000000000000000000000..604a08b43d413726589d0ba32f586eb77f46bc1c --- /dev/null +++ b/research/cv/PDarts/infer/data/config/pdarts.pipeline @@ -0,0 +1,47 @@ +{ + "pdarts": { + "stream_config": { + "deviceId": "0" + }, + "appsrc0": { + "props": { + "blocksize": "409600" + }, + "factory": "appsrc", + "next": "mxpi_tensorinfer0" + }, + "mxpi_tensorinfer0": { + "props": { + "dataSource": "appsrc0", + "modelPath": "../pdartsbin.om", + "waitingTime": "5000", + "outputDeviceId": "-1" + }, + "factory": "mxpi_tensorinfer", + "next": "mxpi_classpostprocessor0" + }, + "mxpi_classpostprocessor0": { + "props": { + "dataSource": "mxpi_tensorinfer0", + "postProcessConfigPath": "../data/config/pdarts.cfg", + "labelPath": "../data/config/cifar10.names", + "postProcessLibPath": "libresnet50postprocess.so" + }, + "factory": "mxpi_classpostprocessor", + "next": "mxpi_dataserialize0" + }, + "mxpi_dataserialize0": { + "props": { + "outputDataKeys": "mxpi_classpostprocessor0" + }, + "factory": "mxpi_dataserialize", + "next": "appsink0" + }, + "appsink0": { + "props": { + "blocksize": "4096000" + }, + "factory": "appsink" + } + } +} diff --git a/research/cv/PDarts/infer/data/preprocess.py b/research/cv/PDarts/infer/data/preprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..68f714d7a5451108094b2d427605bdb890ba3ee8 --- /dev/null +++ b/research/cv/PDarts/infer/data/preprocess.py @@ -0,0 +1,105 @@ +# Copyright 2022 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 """ +import os +import argparse +import numpy as np + +parser = argparse.ArgumentParser(description='preprocess') +parser.add_argument('--dataset', type=str, default='cifar10', help='Dataset, cifar10, imagenet2012') +parser.add_argument('--dataset_path', type=str, default="../../../cifar10/val/", + help='Dataset path.') +parser.add_argument('--output_path', type=str, default="./preprocess_Result", + help='preprocess Result path.') +args_opt = parser.parse_args() + +LABEL_SIZE = 1 +IMAGE_SIZE = 32 +NUM_CHANNELS = 3 +TEST_NUM = 10000 + +def extract_data(filenames): + '''extract_data''' + + labels = None + images = None + + for f in filenames: + bytestream = open(f, 'rb') + buf = bytestream.read(TEST_NUM * (IMAGE_SIZE * IMAGE_SIZE * NUM_CHANNELS + LABEL_SIZE)) + + data = np.frombuffer(buf, dtype=np.uint8) + + data = data.reshape(TEST_NUM, LABEL_SIZE + IMAGE_SIZE * IMAGE_SIZE * NUM_CHANNELS) + + labels_images = np.hsplit(data, [LABEL_SIZE]) + + label = labels_images[0].reshape( + TEST_NUM) + + image = labels_images[1].reshape(TEST_NUM, IMAGE_SIZE, IMAGE_SIZE, + NUM_CHANNELS) + + if not labels: + labels = label + images = image + else: + labels = np.concatenate((labels, label)) + images = np.concatenate((images, image)) + + return labels, images.astype(np.float32) + +def extract_test_data(files_dir): + '''extract cifar files.''' + filenames = [os.path.join(files_dir, 'test_batch.bin'),] + return extract_data(filenames) + + + + +def get_cifar_bin(): + '''generate cifar bin files.''' + batch_size = 1 + + labels, images = extract_test_data(args_opt.dataset_path) + images = images / 255.0 + a = [0.4914, 0.4824, 0.4467] + b = [0.2471, 0.2435, 0.2616] + + images = images.reshape((TEST_NUM, NUM_CHANNELS, IMAGE_SIZE, + IMAGE_SIZE)) + images[:, 0, :, :] = (images[:, 0, :, :] - a[0]) / b[0] + images[:, 1, :, :] = (images[:, 1, :, :] - a[1]) / b[1] + images[:, 2, :, :] = (images[:, 2, :, :] - a[2]) / b[2] + + + img_path = os.path.join(args_opt.output_path, "00_img_data") + label_path = os.path.join(args_opt.output_path, "label.txt") + os.makedirs(img_path) + label_list = [] + + for i in range(TEST_NUM): + img_data = images[i] + img_label = labels[i] + file_name = args_opt.dataset + "_bs" + str(batch_size) + "_" + str(i) + ".bin" + + img_file_path = os.path.join(img_path, file_name) + img_data.tofile(img_file_path) + label_list.append(file_name + ',' + str(img_label)) + np.savetxt(label_path, label_list, fmt="%s") + print("=" * 20, "export bin files finished", "=" * 20) + +if __name__ == '__main__': + get_cifar_bin() diff --git a/research/cv/PDarts/infer/docker_start_infer.sh b/research/cv/PDarts/infer/docker_start_infer.sh new file mode 100644 index 0000000000000000000000000000000000000000..2678ff3f94b2b0be1bb20af554f3787f58b70aef --- /dev/null +++ b/research/cv/PDarts/infer/docker_start_infer.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Copyright 2022 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. + +docker_image=$1 +model_dir=$2 + + +function show_help() { + echo "Usage: docker_start.sh docker_image model_dir data_dir" +} + +function param_check() { + if [ -z "${docker_image}" ]; then + echo "please input docker_image" + show_help + exit 1 + fi + + if [ -z "${model_dir}" ]; then + echo "please input model_dir" + show_help + exit 1 + fi +} + +param_check + +docker run -it -u root \ + --device=/dev/davinci0 \ + --device=/dev/davinci_manager \ + --device=/dev/devmm_svm \ + --device=/dev/hisi_hdc \ + -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ + -v ${model_dir}:${model_dir} \ + ${docker_image} \ + /bin/bash diff --git a/research/cv/PDarts/infer/eval.py b/research/cv/PDarts/infer/eval.py new file mode 100644 index 0000000000000000000000000000000000000000..9cbd73ea3368f16608d95064cbb955574cbccc5f --- /dev/null +++ b/research/cv/PDarts/infer/eval.py @@ -0,0 +1,74 @@ +# Copyright 2022 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. +# ============================================================================ +""" eval_sdk.py """ +import os +import argparse +import numpy as np + +def parse_args(parsers): + """ + Parse commandline arguments. + """ + parsers.add_argument('--images_txt_path', type=str, default="./data/preprocess_Result/label.txt", + help='image path') + parsers.add_argument('--infer_results_txt', type=str, default="./mxbase/build/infer_results.txt") + parsers.add_argument('--result_log_path', type=str, default="./results/eval_mxbase.log") + return parsers + +def read_file_list(input_f): + """ + :param infer file content: + 1.bin 0 + 2.bin 2 + ... + :return image path list, label list + """ + image_file_l = [] + label_l = [] + if not os.path.exists(input_f): + print('input file does not exists.') + with open(input_f, "r") as fs: + for line in fs.readlines(): + line = line.strip('\n').split(',') + file = line[0] + label = int(line[1]) + image_file_l.append(file) + label_l.append(label) + return image_file_l, label_l + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Om pdarts Inference') + parser = parse_args(parser) + args, _ = parser.parse_known_args() + images_txt_path = args.images_txt_path + infer_results_txt = args.infer_results_txt + # load results and label + results = np.loadtxt(infer_results_txt) + file_list, label_list = read_file_list(images_txt_path) + img_size = len(file_list) + + labels = np.array(label_list) + # cal acc + acc_top1 = (results[:, 0] == labels).sum() / img_size + print('Top1 acc:', acc_top1) + + acc_top5 = sum([1 for i in range(img_size) if labels[i] in results[i]]) / img_size + print('Top5 acc:', acc_top5) + + with open(args.result_log_path, 'w') as f: + f.write('Eval size: {} \n'.format(img_size)) + f.write('Top1 acc: {} \n'.format(acc_top1)) + f.write('Top5 acc: {} \n'.format(acc_top5)) diff --git a/research/cv/PDarts/infer/mxbase/CMakeLists.txt b/research/cv/PDarts/infer/mxbase/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4e8146afb22554305c2438fe1074b49ec6739552 --- /dev/null +++ b/research/cv/PDarts/infer/mxbase/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.5.2) +project(PDarts) +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + + +set(TARGET_MAIN PDarts) + +set(ACL_LIB_PATH $ENV{ASCEND_HOME}/nnrt/latest/acllib) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories($ENV{MX_SDK_HOME}/include) +include_directories($ENV{MX_SDK_HOME}/opensource/include) +include_directories($ENV{MX_SDK_HOME}/opensource/include/opencv4) +include_directories($ENV{MX_SDK_HOME}/opensource/include/gstreamer-1.0) +include_directories($ENV{MX_SDK_HOME}/opensource/include/glib-2.0) +include_directories($ENV{MX_SDK_HOME}/opensource/lib/glib-2.0/include) + +link_directories($ENV{MX_SDK_HOME}/lib) +link_directories($ENV{MX_SDK_HOME}/opensource/lib/) + + +add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations) +add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}") +add_compile_options("-Dgoogle=mindxsdk_private") + +add_definitions(-DENABLE_DVPP_INTERFACE) + +include_directories(${ACL_LIB_PATH}/include) +link_directories(${ACL_LIB_PATH}/lib64/) + +add_executable(${TARGET_MAIN} src/main_opencv.cpp src/PDartsClassifyOpencv.cpp) +target_link_libraries(${TARGET_MAIN} ${TARGET_LIBRARY} glog cpprest mxbase libascendcl.so) diff --git a/research/cv/PDarts/infer/mxbase/build.sh b/research/cv/PDarts/infer/mxbase/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..5030919a5fb66c060b7b98bd5e8954e3e9338660 --- /dev/null +++ b/research/cv/PDarts/infer/mxbase/build.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copyright 2022 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. + +export ASCEND_HOME=/usr/local/Ascend +export ASCEND_VERSION=nnrt/latest +export ARCH_PATTERN=. +export LD_LIBRARY_PATH=${MX_SDK_HOME}/lib/modelpostprocessors:${LD_LIBRARY_PATH} + +mkdir -p build +cd build || exit + +function make_plugin() { + if ! cmake ..; + then + echo "cmake failed." + return 1 + fi + + if ! (make); + then + echo "make failed." + return 1 + fi + + return 0 +} + +if make_plugin; +then + echo "INFO: Build successfully." +else + echo "ERROR: Build failed." +fi + +cd - || exit diff --git a/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.cpp b/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31c19001b8ee806842bd87dd55eaab5114b440db --- /dev/null +++ b/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.cpp @@ -0,0 +1,178 @@ +/* + * Copyright 2022 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 "PDartsClassifyOpencv.h" +#include <cstdlib> +#include <memory> +#include <string> +#include <cmath> +#include <vector> +#include <algorithm> +#include <queue> +#include <utility> +#include <fstream> +#include <map> +#include <iostream> +#include "acl/acl.h" +#include "MxBase/DeviceManager/DeviceManager.h" +#include "MxBase/Log/Log.h" + + +APP_ERROR pdarts::Init(const InitParam &initParam) { + deviceId_ = initParam.deviceId; + APP_ERROR ret = MxBase::DeviceManager::GetInstance()->InitDevices(); + if (ret != APP_ERR_OK) { + LogError << "Init devices failed, ret=" << ret << "."; + return ret; + } + ret = MxBase::TensorContext::GetInstance()->SetContext(initParam.deviceId); + if (ret != APP_ERR_OK) { + LogError << "Set context failed, ret=" << ret << "."; + return ret; + } + model_pdarts = std::make_shared<MxBase::ModelInferenceProcessor>(); + ret = model_pdarts->Init(initParam.modelPath, modelDesc_); + if (ret != APP_ERR_OK) { + LogError << "ModelInferenceProcessor init failed, ret=" << ret << "."; + return ret; + } + + return APP_ERR_OK; +} + +APP_ERROR pdarts::DeInit() { + model_pdarts->DeInit(); + MxBase::DeviceManager::GetInstance()->DestroyDevices(); + return APP_ERR_OK; +} + + +APP_ERROR pdarts::ReadBin(const std::string &path, std::vector<std::vector<float>> &dataset) { + std::ifstream inFile(path, std::ios::binary); + float data[3*32*32]; + inFile.read(reinterpret_cast<char *>(&data), sizeof(data)); + std::vector<float> temp(data, data+sizeof(data)/sizeof(data[0])); + dataset.push_back(temp); + + return APP_ERR_OK; +} + + +APP_ERROR pdarts::VectorToTensorBase(const std::vector<std::vector<float>> &input, + MxBase::TensorBase &tensorBase) { + uint32_t dataSize = 1*3*32*32; + float *metaFeatureData = new float[dataSize]; + uint32_t idx = 0; + for (size_t bs = 0; bs < input.size(); bs++) { + for (size_t c = 0; c < input[bs].size(); c++) { + metaFeatureData[idx++] = input[bs][c]; + } + } + MxBase::MemoryData memoryDataDst(dataSize * 4, MxBase::MemoryData::MEMORY_DEVICE, deviceId_); + MxBase::MemoryData memoryDataSrc(reinterpret_cast<void *>(metaFeatureData), + dataSize * 4, MxBase::MemoryData::MEMORY_HOST_MALLOC); + + APP_ERROR ret = MxBase::MemoryHelper::MxbsMallocAndCopy(memoryDataDst, memoryDataSrc); + if (ret != APP_ERR_OK) { + LogError << GetError(ret) << "Memory malloc failed."; + return ret; + } + + std::vector<uint32_t> shape = {1, 3, 32, 32}; + tensorBase = MxBase::TensorBase(memoryDataDst, false, shape, MxBase::TENSOR_DTYPE_FLOAT32); + + return APP_ERR_OK; +} + + +APP_ERROR pdarts::Inference(const std::vector<MxBase::TensorBase> &inputs, + std::vector<MxBase::TensorBase> &outputs) { + auto dtypes = model_pdarts->GetOutputDataType(); + for (size_t i = 0; i < modelDesc_.outputTensors.size(); ++i) { + std::vector<uint32_t> shape = {}; + for (size_t j = 0; j < modelDesc_.outputTensors[i].tensorDims.size(); ++j) { + shape.push_back((uint32_t)modelDesc_.outputTensors[i].tensorDims[j]); + } + MxBase::TensorBase tensor(shape, dtypes[i], MxBase::MemoryData::MemoryType::MEMORY_DEVICE, deviceId_); + APP_ERROR ret = MxBase::TensorBase::TensorBaseMalloc(tensor); + if (ret != APP_ERR_OK) { + LogError << "TensorBaseMalloc failed, ret=" << ret << "."; + return ret; + } + outputs.push_back(tensor); + } + MxBase::DynamicInfo dynamicInfo = {}; + dynamicInfo.dynamicType = MxBase::DynamicType::STATIC_BATCH; + auto startTime = std::chrono::high_resolution_clock::now(); + APP_ERROR ret = model_pdarts->ModelInference(inputs, outputs, dynamicInfo); + auto endTime = std::chrono::high_resolution_clock::now(); + double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); + inferCostTimeMilliSec += costMs; + if (ret != APP_ERR_OK) { + LogError << "ModelInference pdarts failed, ret=" << ret << "."; + return ret; + } + return APP_ERR_OK; +} + +APP_ERROR pdarts::Process(const std::string &image_path, const InitParam &initParam, std::vector<int> &outputs) { + std::vector<MxBase::TensorBase> inputs = {}; + std::vector<MxBase::TensorBase> outputs_tb = {}; + std::string infer_result_path = "./infer_results.txt"; + + std::vector<std::vector<float>> image_data; + ReadBin(image_path, image_data); + + MxBase::TensorBase tensorBase; + APP_ERROR ret = VectorToTensorBase(image_data, tensorBase); + if (ret != APP_ERR_OK) { + LogError << "ToTensorBase failed, ret=" << ret << "."; + return ret; + } + inputs.push_back(tensorBase); + auto startTime = std::chrono::high_resolution_clock::now(); + ret = Inference(inputs, outputs_tb); + + auto endTime = std::chrono::high_resolution_clock::now(); + double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); + inferCostTimeMilliSec += costMs; + if (ret != APP_ERR_OK) { + LogError << "Inference failed, ret=" << ret << "."; + return ret; + } + + if (!outputs_tb[0].IsHost()) { + outputs_tb[0].ToHost(); + } + float *value = reinterpret_cast<float *>(outputs_tb[0].GetBuffer()); + + std::vector<int> idx(10); + for (int i = 0; i < 10; i++) { + idx[i] = i; + } + sort(idx.begin(), idx.end(), [&value] (int i1, int i2) {return value[i1] > value[i2]; }); + + std::ofstream outfile(infer_result_path, std::ios::app); + + if (outfile.fail()) { + LogError << "Failed to open result file: "; + return APP_ERR_COMM_FAILURE; + } + outfile << idx[0] << " " << idx[1] << " " << idx[2] << " " << idx[3] << " " << idx[4] << "\n"; + outfile.close(); + + outputs.push_back(idx[0]); +} diff --git a/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.h b/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.h new file mode 100644 index 0000000000000000000000000000000000000000..f6d4a76cf5a374e5ae8bdf2c37da7a875721eb6a --- /dev/null +++ b/research/cv/PDarts/infer/mxbase/src/PDartsClassifyOpencv.h @@ -0,0 +1,54 @@ +/* + * Copyright 2022 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 MXBASE_PDarts_H +#define MXBASE_PDarts_H +#include <memory> +#include <string> +#include <vector> +#include "acl/acl.h" +#include "MxBase/DvppWrapper/DvppWrapper.h" +#include "MxBase/ModelInfer/ModelInferenceProcessor.h" +#include "MxBase/Tensor/TensorContext/TensorContext.h" +#include "MxBase/CV/Core/DataType.h" + +struct InitParam { + uint32_t deviceId; + bool checkTensor; + std::string modelPath; +}; + +class pdarts { + public: + APP_ERROR Init(const InitParam &initParam); + APP_ERROR DeInit(); + APP_ERROR VectorToTensorBase(const std::vector<std::vector<float>> &input, MxBase::TensorBase &tensorBase); + APP_ERROR Inference(const std::vector<MxBase::TensorBase> &inputs, std::vector<MxBase::TensorBase> &outputs); + APP_ERROR Process(const std::string &image_path, const InitParam &initParam, std::vector<int> &outputs); + APP_ERROR ReadBin(const std::string &path, std::vector<std::vector<float>> &dataset); + // get infer time + double GetInferCostMilliSec() const {return inferCostTimeMilliSec;} + + + private: + std::shared_ptr<MxBase::ModelInferenceProcessor> model_pdarts; + MxBase::ModelDesc modelDesc_; + uint32_t deviceId_ = 0; + // infer time + double inferCostTimeMilliSec = 0.0; +}; + +#endif diff --git a/research/cv/PDarts/infer/mxbase/src/main_opencv.cpp b/research/cv/PDarts/infer/mxbase/src/main_opencv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e0de84dd17f85bf3f2ca4877b05f1e2131804338 --- /dev/null +++ b/research/cv/PDarts/infer/mxbase/src/main_opencv.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 2022 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 <fstream> +#include "MxBase/Log/Log.h" +#include "PDartsClassifyOpencv.h" + +namespace { + const std::string resFileName = "../../results/eval_mxbase.log"; +} // namespace + +void SplitString(const std::string &s, std::vector<std::string> *v, const std::string &c) { + std::string::size_type pos1, pos2; + pos2 = s.find(c); + pos1 = 0; + while (std::string::npos != pos2) { + v->push_back(s.substr(pos1, pos2 - pos1)); + + pos1 = pos2 + c.size(); + pos2 = s.find(c, pos1); + } + + if (pos1 != s.length()) { + v->push_back(s.substr(pos1)); + } +} + +APP_ERROR ReadImagesPath(const std::string &path, std::vector<std::string> *imagesPath, std::vector<int> *imageslabel) { + std::ifstream inFile; + inFile.open(path, std::ios_base::in); + std::string line; + // Check images path file validity + if (inFile.fail()) { + LogError << "Failed to open annotation file: " << path; + return APP_ERR_COMM_OPEN_FAIL; + } + std::vector<std::string> vectorStr_path; + std::string splitStr_path = ","; + // construct label map + while (std::getline(inFile, line)) { + vectorStr_path.clear(); + + SplitString(line, &vectorStr_path, splitStr_path); + std::string str_path = vectorStr_path[0]; + std::string str_label = vectorStr_path[1]; + imagesPath->push_back(str_path); + int label = str_label[0] - '0'; + imageslabel->push_back(label); + } + + inFile.close(); + return APP_ERR_OK; +} + +int main(int argc, char* argv[]) { + InitParam initParam = {}; + initParam.deviceId = 0; + initParam.checkTensor = true; + initParam.modelPath = "../../pdartsbin.om"; + std::string dataPath = "../../data/preprocess_Result/00_img_data/"; + std::string annoPath = "../../data/preprocess_Result/label.txt"; + + auto model_pdarts = std::make_shared<pdarts>(); + APP_ERROR ret = model_pdarts->Init(initParam); + if (ret != APP_ERR_OK) { + LogError << "Tagging init failed, ret=" << ret << "."; + return ret; + } + + std::vector<std::string> imagesPath; + std::vector<int> imageslabel; + ret = ReadImagesPath(annoPath, &imagesPath, &imageslabel); + + if (ret != APP_ERR_OK) { + model_pdarts->DeInit(); + return ret; + } + + int img_size = imagesPath.size(); + LogInfo<< "test image size:"<< img_size; + + std::vector<int> outputs; + for (int i=0; i < img_size; i++) { + ret = model_pdarts->Process(dataPath + imagesPath[i], initParam, outputs); + if (ret !=APP_ERR_OK) { + LogError << "pdarts process failed, ret=" << ret << "."; + model_pdarts->DeInit(); + return ret; + } + } + + float cor = 0; + for (int i = 0; i < img_size; i++) { + int label_now = imageslabel[i]; + if (label_now == outputs[i]) { + cor++; + } + } + + model_pdarts->DeInit(); + + double total_time = model_pdarts->GetInferCostMilliSec() / 1000; + LogInfo<< "total num: "<< img_size<< ",acc total: "<< static_cast<float>(cor/img_size); + LogInfo<< "inferance total cost time: "<< total_time<< ", FPS: "<< img_size/total_time; + + return APP_ERR_OK; +} diff --git a/research/cv/PDarts/infer/sdk/main.py b/research/cv/PDarts/infer/sdk/main.py new file mode 100644 index 0000000000000000000000000000000000000000..2b3c4a1b7f52c20a4138cbdec7ef49ffaa55620b --- /dev/null +++ b/research/cv/PDarts/infer/sdk/main.py @@ -0,0 +1,154 @@ +# Copyright 2022 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. +# ============================================================================ +""" main.py """ +import os +import argparse +import datetime +import json +import numpy as np +from StreamManagerApi import StreamManagerApi +from StreamManagerApi import MxDataInput, InProtobufVector, MxProtobufIn +import MxpiDataType_pb2 as MxpiDataType + + +shape = [1, 3, 32, 32] + + +def parse_args(parsers): + """ + Parse commandline arguments. + """ + parsers.add_argument('--images_txt_path', type=str, default="../data/preprocess_Result/label.txt", + help='image path') + return parsers + + +def read_file_list(input_f): + """ + :param infer file content: + 1.bin 0 + 2.bin 2 + ... + :return image path list, label list + """ + image_file_l = [] + label_l = [] + if not os.path.exists(input_f): + print('input file does not exists.') + with open(input_f, "r") as fs: + for line in fs.readlines(): + line = line.strip('\n').split(',') + files = line[0] + label = int(line[1]) + image_file_l.append(files) + label_l.append(label) + return image_file_l, label_l + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Om PDarts Inference') + parser = parse_args(parser) + args, _ = parser.parse_known_args() + # init stream manager + stream_manager = StreamManagerApi() + ret = stream_manager.InitManager() + if ret != 0: + print("Failed to init Stream manager, ret=%s" % str(ret)) + exit() + + # create streams by pipeline config file + with open("../data/config/pdarts.pipeline", 'rb') as f: + pipeline = f.read() + ret = stream_manager.CreateMultipleStreams(pipeline) + if ret != 0: + print("Failed to create Stream, ret=%s" % str(ret)) + exit() + + # Construct the input of the stream + res_dir_name = 'result' + if not os.path.exists(res_dir_name): + os.makedirs(res_dir_name) + + results_dir = 'results' + if not os.path.exists(results_dir): + os.makedirs(results_dir) + + if not os.path.exists("../results"): + os.makedirs("../results") + + file_list, label_list = read_file_list(args.images_txt_path) + + img_size = len(file_list) + results = [] + + for idx, file in enumerate(file_list): + image_path = os.path.join(args.images_txt_path.replace('label.txt', '00_img_data'), file) + + # Construct the input of the stream + data_input = MxDataInput() + with open(image_path, 'rb') as f: + data = f.read() + data_input.data = data + tensorPackageList1 = MxpiDataType.MxpiTensorPackageList() + tensorPackage1 = tensorPackageList1.tensorPackageVec.add() + tensorVec1 = tensorPackage1.tensorVec.add() + tensorVec1.deviceId = 0 + tensorVec1.memType = 0 + for t in shape: + tensorVec1.tensorShape.append(t) + tensorVec1.dataStr = data_input.data + tensorVec1.tensorDataSize = len(data) + protobufVec1 = InProtobufVector() + protobuf1 = MxProtobufIn() + protobuf1.key = b'appsrc0' + protobuf1.type = b'MxTools.MxpiTensorPackageList' + protobuf1.protobuf = tensorPackageList1.SerializeToString() + protobufVec1.push_back(protobuf1) + + unique_id = stream_manager.SendProtobuf(b'pdarts', b'appsrc0', protobufVec1) + + # Obtain the inference result by specifying streamName and uniqueId. + start_time = datetime.datetime.now() + infer_result = stream_manager.GetResult(b'pdarts', 0) + # Obtain the inference result by specifying streamName and uniqueId. + end_time = datetime.datetime.now() + print('sdk run time: {}'.format((end_time - start_time).microseconds)) + if infer_result.errorCode != 0: + print("GetResultWithUniqueId error. errorCode=%d, errorMsg=%s" % ( + infer_result.errorCode, infer_result.data.decode())) + exit() + # print the infer result + infer_res = infer_result.data.decode() + print("process img: {}, infer result: {}".format(file, infer_res)) + load_dict = json.loads(infer_result.data.decode()) + if load_dict.get('MxpiClass') is None: + with open(res_dir_name + "/" + file.split(".")[0] + '.txt', 'w') as f_write: + f_write.write("") + continue + res_vec = load_dict.get('MxpiClass') + res = [i['classId'] for i in load_dict['MxpiClass']] + results.append(res) + + with open(res_dir_name + "/" + file.split(".")[0] + '_1.txt', 'w') as f_write: + res_list = [str(item.get("classId")) + " " for item in res_vec] + f_write.writelines(res_list) + f_write.write('\n') + + results = np.array(results) + labels = np.array(label_list) + np.savetxt("./results/infer_results.txt", results, fmt='%s') + # destroy streams + stream_manager.DestroyAllStreams() diff --git a/research/cv/PDarts/infer/sdk/run.sh b/research/cv/PDarts/infer/sdk/run.sh new file mode 100644 index 0000000000000000000000000000000000000000..cf3fe47e717b6dc4e66f4d1d2bc82d4c41a79021 --- /dev/null +++ b/research/cv/PDarts/infer/sdk/run.sh @@ -0,0 +1,16 @@ +#!/usr/bin/bash +set -e + +# Simple log helper functions +info() { echo -e "\033[1;34m[INFO ][MxStream] $1\033[1;37m" ; } +warn() { echo >&2 -e "\033[1;31m[WARN ][MxStream] $1\033[1;37m" ; } + +export LD_LIBRARY_PATH=${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:${MX_SDK_HOME}/opensource/lib64:/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:${LD_LIBRARY_PATH} +export GST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner +export GST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins + +#to set PYTHONPATH, import the StreamManagerApi.py +export PYTHONPATH=$PYTHONPATH:${MX_SDK_HOME}/python + +python3 main.py +exit 0 diff --git a/research/cv/PDarts/modelarts/start.py b/research/cv/PDarts/modelarts/start.py new file mode 100644 index 0000000000000000000000000000000000000000..87a29d07e654a462e99844b6109a2c49029037af --- /dev/null +++ b/research/cv/PDarts/modelarts/start.py @@ -0,0 +1,268 @@ +# Copyright 2022 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 +# +# less 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. +# ============================================================================ +"""train the PDarts model""" +try: + from moxing.framework import file + print("import moxing success") +except ModuleNotFoundError as e: + print(f'not modelarts env, error={e}') + +import os +import time +import logging +import argparse +import glob +import datetime + +import moxing as mox +import numpy as np +import mindspore +from mindspore import context +import mindspore.nn as nn +from mindspore.common.tensor import Tensor +from mindspore import export +from mindspore.train.loss_scale_manager import FixedLossScaleManager +from mindspore.train.callback._time_monitor import TimeMonitor +from mindspore.train.callback._loss_monitor import LossMonitor +from mindspore.train import Model +from mindspore.train.serialization import load_checkpoint, load_param_into_net +from mindspore.communication import init +from mindspore.train.model import ParallelMode + +import src.my_utils as my_utils +import src.genotypes as genotypes +from src.loss import SoftmaxCrossEntropyLoss +from src.model import NetworkCIFAR as Network +from src.dataset import create_cifar10_dataset +from src.call_backs import Val_Callback, Set_Attr_CallBack + +parser = argparse.ArgumentParser("cifar") +parser.add_argument('--device_target', type=str, default="Ascend", choices=['Ascend'], + help='device where the code will be implemented (default: CPU)') +parser.add_argument('--local_data_root', default='/cache/', + help='a directory used for transfer data between local path and OBS path') +parser.add_argument("--modelarts_result_dir", type=str, default="/cache/save_model/") +parser.add_argument('--data_url', type=str, + default="cifar-10-binary", help='the training data path') +parser.add_argument('--train_url', type=str, default="./output", + help='the path to save training outputs') +parser.add_argument('--batch_size', type=int, default=128, help='batch size') +parser.add_argument('--load_weight', type=str, default='', + help='load ckpt file path') +parser.add_argument('--no_top', type=str, default='True', + help='whether contains the top fc layer weights') +parser.add_argument('--learning_rate', type=float, + default=0.025, help='init learning rate') +parser.add_argument('--momentum', type=float, default=0.9, help='momentum') +parser.add_argument('--weight_decay', type=float, + default=3e-4, help='weight decay') +parser.add_argument('--epochs', type=int, default=600, + help='num of training epochs') +parser.add_argument('--init_channels', type=int, + default=36, help='num of init channels') +parser.add_argument('--layers', type=int, default=20, + help='total number of layers') +parser.add_argument('--auxiliary', action='store_true', + default=True, help='use auxiliary tower') +parser.add_argument('--auxiliary_weight', type=float, + default=0.4, help='weight for auxiliary loss') +parser.add_argument('--drop_path_prob', type=float, + default=0.3, help='drop path probability') +parser.add_argument('--arch', type=str, default='PDARTS', + help='which architecture to use') +parser.add_argument('--amp_level', type=str, default='O3', help='') +parser.add_argument('--optimizer', type=str, + default='Momentum', help='SGD or Momentum') +parser.add_argument('--cutout_length', default=16, help='use cutout') +parser.add_argument("--modelarts_ckpt_dir", type=str, default="/cache/ckpt") + +args = parser.parse_args() + +CIFAR_CLASSES = 10 + +def modelarts_result2obs(FLAGS): + """ + Copy debug data from modelarts to obs. + According to the switch flags, the debug data may contains auto tune repository, + dump data for precision comparison, even the computation graph and profiling data. + """ + mox.file.copy_parallel(src_url=FLAGS.local_data_root, dst_url=FLAGS.train_url) + print("===>>>Copy Event or Checkpoint from modelarts dir:{} to obs:{}".format(FLAGS.local_data_root, + FLAGS.train_url)) + files = os.listdir() + print("===>>>current Files:", files) + mox.file.copy(src_url='pdarts.air', dst_url=FLAGS.train_url + '/pdarts.air') + + +def export_AIR(opt): + """start modelarts export""" + ckpt_list = glob.glob(opt.train_url + "/*" + "/checkpoint" + "/model*.ckpt") + if not ckpt_list: + print("ckpt file not generated.") + + ckpt_list.sort(key=os.path.getmtime) + ckpt_model = ckpt_list[-1] + print("checkpoint path", ckpt_model) + if opt.arch == 'PDARTS': + genotype = genotypes.PDARTS + print('---------Genotype---------') + print(genotype) + print('--------------------------') + network = Network(opt.init_channels, CIFAR_CLASSES, + opt.layers, opt.auxiliary, genotype) + network.training = False + network.drop_path_prob = opt.drop_path_prob * 300 / opt.epochs + keep_prob = 1. - network.drop_path_prob + epoch_mask = [] + for dummy_i in range(opt.layers): + layer_mask = [] + for dummy_j in range(5 * 2): + mask = np.array([np.random.binomial(1, p=keep_prob) + for k in range(opt.batch_size)]) + mask = mask[:, np.newaxis, np.newaxis, np.newaxis] + mask = Tensor(mask, mindspore.float16) + layer_mask.append(mask) + epoch_mask.append(layer_mask) + network.epoch_mask = epoch_mask + param_dict = load_checkpoint(ckpt_model) + load_param_into_net(network, param_dict) + input_arr = Tensor(np.zeros([1, 3, 32, 32], np.float32)) + export(network, input_arr, file_name="pdarts", file_format='AIR') + print(os.path.dirname("pdarts.air")) + + +def cosine_lr(base_lr, decay_steps, total_steps): + lr_each_step = [] + for i in range(total_steps): + step_ = min(i, decay_steps) + new_lr = base_lr * 0.5 * (1 + np.cos(np.pi * step_ / decay_steps)) + lr_each_step.append(new_lr) + lr_each_step = np.array(lr_each_step).astype(np.float32) + return lr_each_step + + +def main(): + device_id = int(os.getenv('DEVICE_ID')) + device_num = int(os.getenv('RANK_SIZE')) + print(f'device_id:{device_id}') + print(f'device_num:{device_num}') + context.set_context(mode=context.GRAPH_MODE, + device_target=args.device_target) + context.set_context(device_id=device_id) + context.set_context(enable_graph_kernel=True) + if device_num > 1: + init() + context.set_auto_parallel_context(device_num=device_num, + parallel_mode=ParallelMode.DATA_PARALLEL, + gradients_mean=True) + + print(genotypes.Genotype) + if args.arch == 'PDARTS': + genotype = genotypes.PDARTS + print('---------Genotype---------') + logging.info(genotype) + print('--------------------------') + network = Network(args.init_channels, CIFAR_CLASSES, + args.layers, args.auxiliary, genotype) + my_utils.print_trainable_params_count(network) + + if args.load_weight != '' and args.load_weight != 'None' and args.load_weight is not None: + param_dict = load_checkpoint(args.load_weight) + if args.no_top == 'True': + print('remove top fc layer weights...') + param_dict.pop('auxiliary_head.classifier.weight') + param_dict.pop('auxiliary_head.classifier.bias') + param_dict.pop('classifier.weight') + param_dict.pop('classifier.bias') + param_dict.pop('moments.auxiliary_head.classifier.weight') + param_dict.pop('moments.auxiliary_head.classifier.bias') + param_dict.pop('moments.classifier.weight') + param_dict.pop('moments.classifier.bias') + load_param_into_net(network, param_dict) + + if args.data_url.startswith('s3://') or args.data_url.startswith('obs://'): + data_url_cache = os.path.join(args.local_data_root, 'data') + file.copy_parallel(args.data_url, data_url_cache) + args.data_url = data_url_cache + + train_path = os.path.join(args.data_url, 'train') + train_dataset = create_cifar10_dataset( + train_path, True, batch_size=args.batch_size, shuffle=True, cutout_length=args.cutout_length) + val_path = os.path.join(args.data_url, 'val') + val_dataset = create_cifar10_dataset( + val_path, False, batch_size=128, shuffle=False) + + # learning rate setting + step_size = train_dataset.get_dataset_size() + print(f'step_size:{step_size}') + lr = args.learning_rate + lr = cosine_lr(lr, args.epochs * step_size, args.epochs * step_size) + lr = Tensor(lr) + + if args.optimizer == 'SGD': + net_opt = nn.SGD( + network.trainable_params(), + lr, + momentum=args.momentum, + weight_decay=args.weight_decay, + nesterov=True, + loss_scale=1024 + ) + elif args.optimizer == 'Momentum': + net_opt = nn.Momentum( + network.trainable_params(), + lr, + momentum=args.momentum, + weight_decay=args.weight_decay, + use_nesterov=True, + loss_scale=1024 + ) + + net_loss = SoftmaxCrossEntropyLoss(args.auxiliary, args.auxiliary_weight) + loss_scale = FixedLossScaleManager(1024, drop_overflow_update=False) + model = Model(network, net_loss, net_opt, metrics={'loss', 'top_1_accuracy', 'top_5_accuracy'}, + amp_level=args.amp_level, loss_scale_manager=loss_scale) + + set_attr_cb = Set_Attr_CallBack( + network, args.drop_path_prob, args.epochs, args.layers, args.batch_size) + if device_num == 1 or device_id == 0: + loss_cb = LossMonitor() + time_cb = TimeMonitor() + val_callback = Val_Callback(model, train_dataset, val_dataset, args.train_url, + prefix='PDarts', network=network, img_size=32, is_eval_train_dataset=True) + callbacks = [loss_cb, time_cb, val_callback, set_attr_cb] + else: + callbacks = [set_attr_cb] + model.train(args.epochs, train_dataset, + callbacks=callbacks, dataset_sink_mode=True) + + # start export air + if device_id == 0: + print("start to export air model") + start = datetime.datetime.now() + export_AIR(args) + end = datetime.datetime.now() + print("===>>end up exporting air model, time use:{}(s)".format((end - start).seconds)) + + # copy result from modelarts to obs + modelarts_result2obs(args) + + +if __name__ == '__main__': + start_time = time.time() + main() + end_time = time.time() + duration = end_time - start_time + logging.info('Total time: %ds.', duration) diff --git a/research/cv/PDarts/scripts/docker_start.sh b/research/cv/PDarts/scripts/docker_start.sh new file mode 100644 index 0000000000000000000000000000000000000000..6b452b3d3f4b1596501ed63d6047052717115c0f --- /dev/null +++ b/research/cv/PDarts/scripts/docker_start.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Copyright (c) 2022. 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. +# ============================================================================ + +docker_image=$1 +data_dir=$2 +model_dir=$3 + +docker run -it -u root --ipc=host \ + --device=/dev/davinci0 \ + --device=/dev/davinci1 \ + --device=/dev/davinci2 \ + --device=/dev/davinci3 \ + --device=/dev/davinci4 \ + --device=/dev/davinci5 \ + --device=/dev/davinci6 \ + --device=/dev/davinci7 \ + --device=/dev/davinci_manager \ + --device=/dev/devmm_svm \ + --device=/dev/hisi_hdc \ + --privileged \ + -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ + -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons \ + -v ${data_dir}:${data_dir} \ + -v ${model_dir}:${model_dir} \ + -v /root/ascend/log:/root/ascend/log ${docker_image} /bin/bash \ No newline at end of file