diff --git a/research/cv/CGAN/infer/convert/convert_om.sh b/research/cv/CGAN/infer/convert/convert_om.sh new file mode 100644 index 0000000000000000000000000000000000000000..21d3e5188220d019ec6a82ce91013ccb6403f5fc --- /dev/null +++ b/research/cv/CGAN/infer/convert/convert_om.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# 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. + +if [ $# -ne 2 ] +then + echo "Wrong parameter format." + echo "Usage:" + echo " bash $0 [INPUT_AIR_PATH] [OUTPUT_OM_PATH_NAME]" + echo "Example: " + echo " bash convert_om.sh xxx.air xx" + + exit 1 +fi + +input_air_path=$1 +output_om_path=$2 + +export install_path=/usr/local/Ascend/ + +export ASCEND_ATC_PATH=${install_path}/atc +export LD_LIBRARY_PATH=${install_path}/atc/lib64:$LD_LIBRARY_PATH +export PATH=/usr/local/python3.7.5/bin:${install_path}/atc/ccec_compiler/bin:${install_path}/atc/bin:$PATH +export PYTHONPATH=${install_path}/atc/python/site-packages:${install_path}/latest/atc/python/site-packages/auto_tune.egg/auto_tune:${install_path}/atc/python/site-packages/schedule_search.egg +export ASCEND_OPP_PATH=${install_path}/opp + +export ASCEND_SLOG_PRINT_TO_STDOUT=1 + +echo "Input AIR file path: ${input_air_path}" +echo "Output OM file path: ${output_om_path}" + +atc --input_format=ND \ + --framework=1 \ + --model="${input_air_path}" \ + --input_shape="x:1,100;a:1,10" \ + --output="${output_om_path}" \ + --precision_mode=allow_fp32_to_fp16 \ + --soc_version=Ascend310 \ + --op_select_implmode=high_precision diff --git a/research/cv/CGAN/infer/docker_start_infer.sh b/research/cv/CGAN/infer/docker_start_infer.sh new file mode 100644 index 0000000000000000000000000000000000000000..64cf90a2311bdfb21d68a4e90e08602670fdf632 --- /dev/null +++ b/research/cv/CGAN/infer/docker_start_infer.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# 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. + +docker_image=$1 +data_dir=$2 + +function show_help() { + echo "Usage: docker_start.sh docker_image data_dir" +} + +function param_check() { + if [ -z "${docker_image}" ]; then + echo "please input docker_image" + show_help + exit 1 + fi + + if [ -z "${data_dir}" ]; then + echo "please input data_dir" + show_help + exit 1 + fi +} + +param_check + +docker run -it \ + --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 ${data_dir}:${data_dir} \ + ${docker_image} \ + /bin/bash diff --git a/research/cv/CGAN/infer/mxbase/CMakeLists.txt b/research/cv/CGAN/infer/mxbase/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2a1870136da9400b5d92f5a3ece7ba66e632f874 --- /dev/null +++ b/research/cv/CGAN/infer/mxbase/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.14.0) +project(cgan) +set(TARGET_MAIN Cgan) + +add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) +add_definitions(-Dgoogle=mindxsdk_private) +add_compile_options(-std=c++11 -fPIE -fstack-protector-all -fPIC -Wall) +add_link_options(-Wl,-z,relro,-z,now,-z,noexecstack -s -pie) +# Check environment variable +if(NOT DEFINED ENV{ASCEND_HOME}) + message(FATAL_ERROR "please define environment variable:ASCEND_HOME") +endif() +if(NOT DEFINED ENV{ARCH_PATTERN}) + message(WARNING "please define environment variable:ARCH_PATTERN") +endif() +set(ACL_LIB_PATH $ENV{ASCEND_HOME}/nnrt/latest/acllib) +set(MXBASE_ROOT_DIR $ENV{MX_SDK_HOME}) +set(MXBASE_INC ${MXBASE_ROOT_DIR}/include) +set(MXBASE_LIB_DIR ${MXBASE_ROOT_DIR}/lib) +set(MXBASE_POST_LIB_DIR ${MXBASE_ROOT_DIR}/lib/modelpostprocessors) +set(MXBASE_POST_PROCESS_DIR ${MXBASE_ROOT_DIR}/include/MxBase/postprocess/include) + +set(OPENSOURCE_DIR $ENV{MX_SDK_HOME}/opensource) + +include_directories(src) +include_directories(${ACL_INC_DIR}) +include_directories(${OPENSOURCE_DIR}/include) +include_directories(${OPENSOURCE_DIR}/include/opencv4) + + +include_directories(${MXBASE_INC}) +include_directories(${MXBASE_POST_PROCESS_DIR}) + +link_directories(${ACL_LIB_DIR}) +link_directories(${OPENSOURCE_DIR}/lib) +link_directories(${MXBASE_LIB_DIR}) +link_directories(${MXBASE_POST_LIB_DIR}) + + +add_executable(${TARGET_MAIN} src/main.cpp src/Cgan.cpp) + +target_link_libraries(${TARGET_MAIN} glog cpprest mxbase opencv_world) + +install(TARGETS ${TARGET_MAIN} RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/) \ No newline at end of file diff --git a/research/cv/CGAN/infer/mxbase/build.sh b/research/cv/CGAN/infer/mxbase/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..3ae8c91cfbe8a2aad3f924134aadaec4f58e1024 --- /dev/null +++ b/research/cv/CGAN/infer/mxbase/build.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# 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. + +path_cur=$(dirname $0) + +function check_env() +{ + # set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user + if [ ! "${ASCEND_VERSION}" ]; then + export ASCEND_VERSION=ascend-toolkit/latest + echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}" + else + echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user" + fi + + if [ ! "${ARCH_PATTERN}" ]; then + # set ARCH_PATTERN to ./ when it was not specified by user + export ARCH_PATTERN=./ + echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}" + else + echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user" + fi +} + +function build_cgan() +{ + cd $path_cur + rm -rf build + mkdir -p build + cd build + cmake .. + make + ret=$? + if [ ${ret} -ne 0 ]; then + echo "Failed to build cgan." + exit ${ret} + fi + make install +} + +check_env +build_cgan diff --git a/research/cv/CGAN/infer/mxbase/src/Cgan.cpp b/research/cv/CGAN/infer/mxbase/src/Cgan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c99aa5974d75a4ac7a25193bb45d1ed023a8da4 --- /dev/null +++ b/research/cv/CGAN/infer/mxbase/src/Cgan.cpp @@ -0,0 +1,207 @@ +/** + * 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 "Cgan.h" +#include "MxBase/DeviceManager/DeviceManager.h" +#include "MxBase/Log/Log.h" + +namespace { + const float NORMALIZE_MEAN = 255/2; + const float NORMALIZE_STD = 255/2; + const uint32_t OUTPUT_HEIGHT = 28; + const uint32_t OUTPUT_WIDTH = 28; + const uint32_t CHANNEL = 1; +} + +void PrintTensorShape(const std::vector<MxBase::TensorDesc> &tensorDescVec, const std::string &tensorName) { + LogInfo << "The shape of " << tensorName << " is as follows:"; + for (size_t i = 0; i < tensorDescVec.size(); ++i) { + LogInfo << " Tensor " << i << ":"; + for (size_t j = 0; j < tensorDescVec[i].tensorDims.size(); ++j) { + LogInfo << " dim: " << j << ": " << tensorDescVec[i].tensorDims[j]; + } + } +} + +APP_ERROR Cgan::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_ = std::make_shared<MxBase::ModelInferenceProcessor>(); + ret = model_->Init(initParam.modelPath, modelDesc_); + if (ret != APP_ERR_OK) { + LogError << "ModelInferenceProcessor init failed, ret=" << ret << "."; + return ret; + } + savePath_ = initParam.savePath; + PrintTensorShape(modelDesc_.inputTensors, "Model Input Tensors"); + PrintTensorShape(modelDesc_.outputTensors, "Model Output Tensors"); + + return APP_ERR_OK; +} + +APP_ERROR Cgan::DeInit() { + model_->DeInit(); + MxBase::DeviceManager::GetInstance()->DestroyDevices(); + return APP_ERR_OK; +} + +APP_ERROR Cgan::CVMatToTensorBase(const cv::Mat& imageMat, MxBase::TensorBase *tensorBase) { + uint32_t dataSize = 1; + for (size_t i = 0; i < modelDesc_.inputTensors.size(); ++i) { + std::vector<uint32_t> shape = {}; + for (size_t j = 0; j < modelDesc_.inputTensors[i].tensorDims.size(); ++j) { + shape.push_back((uint32_t)modelDesc_.inputTensors[i].tensorDims[j]); + } + for (uint32_t s = 0; s < shape.size(); ++s) { + dataSize *= shape[s]; + } + } + + // mat ND + size_t N = imageMat.rows, D = imageMat.cols; + float* mat_data = new float[dataSize]; + + for (size_t i = 0; i < N; i++) { + for (size_t j = 0; j < D; j++) { + int id = i * D + j; + mat_data[id] = imageMat.at<float>(i, j); + } + } + + MxBase::MemoryData memoryDataDst(dataSize, MxBase::MemoryData::MEMORY_DEVICE, deviceId_); + MxBase::MemoryData memoryDataSrc(reinterpret_cast<void*>(&mat_data[0]), + dataSize, 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, 100}; + *tensorBase = MxBase::TensorBase(memoryDataDst, false, shape, MxBase::TENSOR_DTYPE_FLOAT32); + return APP_ERR_OK; +} + +APP_ERROR Cgan::Inference(const std::vector<MxBase::TensorBase> &inputs, + std::vector<MxBase::TensorBase> *outputs) { + auto dtypes = model_->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; + dynamicInfo.batchSize = 1; + + + APP_ERROR ret = model_->ModelInference(inputs, *outputs, dynamicInfo); + if (ret != APP_ERR_OK) { + LogError << "ModelInference failed, ret=" << ret << "."; + return ret; + } + return APP_ERR_OK; +} + +APP_ERROR Cgan::PostProcess(std::vector<MxBase::TensorBase> outputs, cv::Mat *resultImg) { + APP_ERROR ret = outputs[0].ToHost(); + if (ret != APP_ERR_OK) { + LogError << GetError(ret) << "tohost fail."; + return ret; + } + float *outputPtr = reinterpret_cast<float *>(outputs[0].GetBuffer()); + + size_t H = OUTPUT_HEIGHT, W = OUTPUT_WIDTH; + + for (size_t h = 0; h < H; h++) { + for (size_t w = 0; w < W; w++) { + float tmpNum = *(outputPtr + h * W + w) * NORMALIZE_STD + NORMALIZE_MEAN; + resultImg->at<uchar>(h, w) = static_cast<int>(tmpNum); + } + } + + return APP_ERR_OK; +} + +APP_ERROR Cgan::SaveResult(const cv::Mat &resultImg, const std::string &imgName) { + DIR *dirPtr = opendir(savePath_.c_str()); + if (dirPtr == nullptr) { + std::string path1 = "mkdir -p " + savePath_; + system(path1.c_str()); + } + cv::imwrite(savePath_ + "/" + imgName, resultImg); + return APP_ERR_OK; +} + +APP_ERROR Cgan::Process(const cv::Mat &imageMat, const cv::Mat &label, const std::string &imgName) { + std::vector<MxBase::TensorBase> inputs = {}; + std::vector<MxBase::TensorBase> outputs = {}; + + MxBase::TensorBase tensorBase; + APP_ERROR ret = CVMatToTensorBase(imageMat, &tensorBase); + if (ret != APP_ERR_OK) { + LogError << "CVMatToTensorBase failed, ret=" << ret << "."; + return ret; + } + inputs.push_back(tensorBase); + + MxBase::TensorBase imgLabels; + ret = CVMatToTensorBase(label, &imgLabels); + if (ret != APP_ERR_OK) { + LogError << "CVMatToTensorBase failed, ret=" << ret << "."; + return ret; + } + inputs.push_back(imgLabels); + auto startTime = std::chrono::high_resolution_clock::now(); + ret = Inference(inputs, &outputs); + auto endTime = std::chrono::high_resolution_clock::now(); + double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); // save time + inferCostTimeMilliSec += costMs; + if (ret != APP_ERR_OK) { + LogError << "Inference failed, ret=" << ret << "."; + return ret; + } + cv::Mat resultImg(OUTPUT_HEIGHT, OUTPUT_WIDTH, CV_8UC1); + ret = PostProcess(outputs, &resultImg); + if (ret != APP_ERR_OK) { + LogError << "PostProcess failed, ret=" << ret << "."; + return ret; + } + ret = SaveResult(resultImg, imgName); + if (ret != APP_ERR_OK) { + LogError << "Save infer results into file failed. ret = " << ret << "."; + return ret; + } + + return APP_ERR_OK; +} diff --git a/research/cv/CGAN/infer/mxbase/src/Cgan.h b/research/cv/CGAN/infer/mxbase/src/Cgan.h new file mode 100644 index 0000000000000000000000000000000000000000..81e889c4e657a35a786350fcae092b5900944cf5 --- /dev/null +++ b/research/cv/CGAN/infer/mxbase/src/Cgan.h @@ -0,0 +1,61 @@ +/** + * 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 CGAN_H +#define CGAN_H +#include <dirent.h> +#include <memory> +#include <vector> +#include <map> +#include <string> +#include <fstream> +#include <iostream> +#include <opencv2/opencv.hpp> +#include "MxBase/Log/Log.h" +#include "MxBase/DvppWrapper/DvppWrapper.h" +#include "MxBase/ModelInfer/ModelInferenceProcessor.h" +#include "MxBase/Tensor/TensorContext/TensorContext.h" +#include "MxBase/DeviceManager/DeviceManager.h" + +struct InitParam { + uint32_t deviceId; + std::string savePath; + std::string modelPath; +}; + +class Cgan { + public: + APP_ERROR Init(const InitParam &initParam); + APP_ERROR DeInit(); + APP_ERROR CVMatToTensorBase(const cv::Mat &imageMat, MxBase::TensorBase *tensorBase); + APP_ERROR Inference(const std::vector<MxBase::TensorBase> &inputs, std::vector<MxBase::TensorBase> *outputs); + APP_ERROR PostProcess(std::vector<MxBase::TensorBase> outputs, cv::Mat *resultImg); + APP_ERROR Process(const cv::Mat &imageMat, const cv::Mat &label, const std::string &imgName); + // get infer time + double GetInferCostMilliSec() const {return inferCostTimeMilliSec;} + + private: + APP_ERROR SaveResult(const cv::Mat &resultImg, const std::string &imgName); + std::shared_ptr<MxBase::ModelInferenceProcessor> model_; + std::string savePath_; + MxBase::ModelDesc modelDesc_; + uint32_t deviceId_ = 0; + // infer time + double inferCostTimeMilliSec = 0.0; +}; + + +#endif diff --git a/research/cv/CGAN/infer/mxbase/src/main.cpp b/research/cv/CGAN/infer/mxbase/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..686fa50c7995102e50b4b5c52e0e7c991960aa31 --- /dev/null +++ b/research/cv/CGAN/infer/mxbase/src/main.cpp @@ -0,0 +1,96 @@ +/** + * 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 "Cgan.h" +#include <opencv2/opencv.hpp> + +int main(int argc, char* argv[]) { + if (argc <= 1) { + LogWarn << "Please input data path, such as '../data'."; + return APP_ERR_OK; + } + + InitParam initParam = {}; + initParam.deviceId = 0; + initParam.modelPath = "../data/model/CGAN.om"; + initParam.savePath = "../data/mxbase_result"; + auto cgan = std::make_shared<Cgan>(); + APP_ERROR ret = cgan->Init(initParam); + if (ret != APP_ERR_OK) { + LogError << "Cgan init failed, ret=" << ret << "."; + return ret; + } + + std::string dataPath = argv[1]; + + int imgNum = 1; + int input_dim = 100; + int n_image = 200; + int n_col = 20; + auto startTime = std::chrono::high_resolution_clock::now(); + + cv::Mat latent_code_eval = cv::Mat(n_image, input_dim, CV_32FC1); + cv::randn(latent_code_eval, 0, 1); + + cv::Mat label_eval = cv::Mat::zeros(n_image, 10, CV_32FC1); + for (int i = 0; i < n_image; i++) { + int j = i / n_col; + label_eval.at<float>(i, j) = 1; + } + for (int i = 0; i < n_image; i++) { + std::string imgName = std::to_string(i) + ".png"; + cv::Mat image; + cv::Mat label; + image = latent_code_eval.rowRange(i, i+1).clone(); + label = label_eval.rowRange(i, i+1).clone(); + ret = cgan->Process(image, label, imgName); + if (ret != APP_ERR_OK) { + LogError << "Cgan process failed, ret=" << ret << "."; + cgan->DeInit(); + return ret; + } + } + + std::vector<cv::Mat> results; + std::vector<cv::Mat> images; + for (int i = 0; i < n_image; i++) { + std::string filepath = dataPath + "/mxbase_result/" + std::to_string(i) + ".png"; + cv::Mat image = cv::imread(filepath); + images.push_back(image); + + if ((i + 1) % n_col == 0) { + cv::Mat result; + cv::hconcat(images, result); + LogInfo << "result" << result.size(); + images.clear(); + results.push_back(result); + } + + if (i + 1 == n_image) { + cv::Mat output; + cv::vconcat(results, output); + std::string resultpath = "../data/mxbase_result/result.png"; + cv::imwrite(resultpath, output); + } + } + + auto endTime = std::chrono::high_resolution_clock::now(); + cgan->DeInit(); + double costMilliSecs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); + double fps = 1000.0 * imgNum / cgan->GetInferCostMilliSec(); + LogInfo << "[Process Delay] cost: " << costMilliSecs << " ms\tfps: " << fps << " imgs/sec"; + return APP_ERR_OK; +} diff --git a/research/cv/CGAN/infer/sdk/api/infer.py b/research/cv/CGAN/infer/sdk/api/infer.py new file mode 100644 index 0000000000000000000000000000000000000000..0cf788045e4707e23ebf22a3c8ffbe636b4bffac --- /dev/null +++ b/research/cv/CGAN/infer/sdk/api/infer.py @@ -0,0 +1,126 @@ +# 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. +# ============================================================================ +""" Model Infer """ +import json +import logging + +import MxpiDataType_pb2 as MxpiDataType +from StreamManagerApi import StreamManagerApi, MxDataInput, InProtobufVector, MxProtobufIn, StringVector +from config import config as cfg + + +class SdkApi: + """ Class SdkApi """ + INFER_TIMEOUT = cfg.INFER_TIMEOUT + STREAM_NAME = cfg.STREAM_NAME + + def __init__(self, pipeline_cfg): + self.pipeline_cfg = pipeline_cfg + self._stream_api = None + self._data_input = None + self._device_id = None + + def init(self): + """ Initialize Stream """ + with open(self.pipeline_cfg, 'r') as fp: + self._device_id = int( + json.loads(fp.read())[self.STREAM_NAME]["stream_config"] + ["deviceId"]) + print(f"The device id: {self._device_id}.") + + # create api + self._stream_api = StreamManagerApi() + + # init stream mgr + ret = self._stream_api.InitManager() + if ret != 0: + print(f"Failed to init stream manager, ret={ret}.") + return False + + # create streams + with open(self.pipeline_cfg, 'rb') as fp: + pipe_line = fp.read() + + ret = self._stream_api.CreateMultipleStreams(pipe_line) + if ret != 0: + print(f"Failed to create stream, ret={ret}.") + return False + + self._data_input = MxDataInput() + return True + + def __del__(self): + if not self._stream_api: + return + + self._stream_api.DestroyAllStreams() + + def _send_protobuf(self, stream_name, plugin_id, element_name, buf_type, + pkg_list): + """ Send Stream """ + protobuf = MxProtobufIn() + protobuf.key = element_name.encode("utf-8") + protobuf.type = buf_type + protobuf.protobuf = pkg_list.SerializeToString() + protobuf_vec = InProtobufVector() + protobuf_vec.push_back(protobuf) + err_code = self._stream_api.SendProtobuf(stream_name, plugin_id, + protobuf_vec) + if err_code != 0: + logging.error( + "Failed to send data to stream, stream_name(%s), plugin_id(%s), element_name(%s), " + "buf_type(%s), err_code(%s).", stream_name, plugin_id, + element_name, buf_type, err_code) + return False + return True + + def send_tensor_input(self, stream_name, plugin_id, element_name, + input_data, input_shape, data_type): + """ Send Tensor """ + tensor_list = MxpiDataType.MxpiTensorPackageList() + tensor_pkg = tensor_list.tensorPackageVec.add() + # init tensor vector + tensor_vec = tensor_pkg.tensorVec.add() + tensor_vec.deviceId = self._device_id + tensor_vec.memType = 0 + tensor_vec.tensorShape.extend(input_shape) + tensor_vec.tensorDataType = data_type + tensor_vec.dataStr = input_data + tensor_vec.tensorDataSize = len(input_data) + + buf_type = b"MxTools.MxpiTensorPackageList" + return self._send_protobuf(stream_name, plugin_id, element_name, + buf_type, tensor_list) + + def get_result(self, stream_name, out_plugin_id=0): + """ Get Result """ + keys = [b"mxpi_tensorinfer0"] + keyVec = StringVector() + for key in keys: + keyVec.push_back(key) + infer_result = self._stream_api.GetProtobuf(stream_name, 0, keyVec) + print(infer_result) + if infer_result.size() == 0: + print("infer_result is null") + exit() + + if infer_result[0].errorCode != 0: + print("GetProtobuf error. errorCode=%d" % ( + infer_result[0].errorCode)) + exit() + + TensorList = MxpiDataType.MxpiTensorPackageList() + TensorList.ParseFromString(infer_result[0].messageBuf) + return TensorList diff --git a/research/cv/CGAN/infer/sdk/config/cgan.pipeline b/research/cv/CGAN/infer/sdk/config/cgan.pipeline new file mode 100644 index 0000000000000000000000000000000000000000..7263312e0ea40c307b15491e2e4cb0970d13f737 --- /dev/null +++ b/research/cv/CGAN/infer/sdk/config/cgan.pipeline @@ -0,0 +1,35 @@ +{ + "im_cgan": { + "stream_config": { + "deviceId": "0" + }, + "appsrc0": { + "props": { + "blocksize": "409600" + }, + "factory": "appsrc", + "next": "mxpi_tensorinfer0:0" + }, + "appsrc1": { + "props": { + "blocksize": "409600" + }, + "factory": "appsrc", + "next": "mxpi_tensorinfer0:1" + }, + "mxpi_tensorinfer0": { + "props": { + "dataSource": "appsrc0,appsrc1", + "modelPath": "../data/model/CGAN.om" + }, + "factory": "mxpi_tensorinfer", + "next": "appsink0" + }, + "appsink0": { + "props": { + "blocksize": "4096000" + }, + "factory": "appsink" + } + } +} diff --git a/research/cv/CGAN/infer/sdk/config/config.py b/research/cv/CGAN/infer/sdk/config/config.py new file mode 100644 index 0000000000000000000000000000000000000000..79de7b4ce4e0b0fac2d9ae0301136e7d3efb7caa --- /dev/null +++ b/research/cv/CGAN/infer/sdk/config/config.py @@ -0,0 +1,22 @@ +# 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. +# ============================================================================ +""" Model Config """ +STREAM_NAME = "im_cgan" + +INFER_TIMEOUT = 100000 + +TENSOR_DTYPE_FLOAT32 = 0 +TENSOR_DTYPE_FLOAT16 = 1 +TENSOR_DTYPE_INT8 = 2 diff --git a/research/cv/CGAN/infer/sdk/main.py b/research/cv/CGAN/infer/sdk/main.py new file mode 100644 index 0000000000000000000000000000000000000000..9fcee32a7199b4a95f1ba1a34dbf67d8a89d6554 --- /dev/null +++ b/research/cv/CGAN/infer/sdk/main.py @@ -0,0 +1,119 @@ +# 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. +# ============================================================================ +""" Model Main """ +import os +import time +import argparse +import itertools +import numpy as np +import matplotlib.pyplot as plt +from api.infer import SdkApi +from config import config as cfg + +def parser_args(): + """ Args Setting """ + parser = argparse.ArgumentParser(description="cgan inference") + + parser.add_argument( + "--pipeline_path", + type=str, + required=False, + default="config/cgan.pipeline", + help="image file path. The default is 'config/cgan.pipeline'. ") + + parser.add_argument( + "--infer_result_dir", + type=str, + required=False, + default="../data/sdk_result", + help= + "cache dir of inference result. The default is '../data/sdk_result'.") + + args_ = parser.parse_args() + return args_ + +def image_inference(pipeline_path, stream_name, result_dir): + """ Image Inference """ + # init stream manager + sdk_api = SdkApi(pipeline_path) + if not sdk_api.init(): + exit(-1) + + if not os.path.exists(result_dir): + os.makedirs(result_dir) + + img_data_plugin_id = 0 + img_label_plugin_id = 1 + + input_dim = 100 + n_image = 200 + n_col = 20 + n_cow = 10 + latent_code_eval = np.random.randn(n_image, input_dim).astype(np.float32) + + label_eval = np.zeros((n_image, 10)).astype(np.float32) + for i in range(n_image): + j = i // n_col + label_eval[i][j] = 1 + label_eval = label_eval.astype(np.float32) + + fake = [] + for idx in range(n_image): + img_np = latent_code_eval[idx].reshape(1, 100) + label_np = label_eval[idx].reshape(1, 10) + + start_time = time.time() + + # set img data + sdk_api.send_tensor_input(stream_name, img_data_plugin_id, "appsrc0", + img_np.tobytes(), img_np.shape, cfg.TENSOR_DTYPE_FLOAT32) + + # set label data + sdk_api.send_tensor_input(stream_name, img_label_plugin_id, "appsrc1", + label_np.tobytes(), label_np.shape, cfg.TENSOR_DTYPE_FLOAT32) + + result = sdk_api.get_result(stream_name) + end_time = time.time() - start_time + print(f"The image({idx}) inference time is {end_time}") + data = np.frombuffer(result.tensorPackageVec[0].tensorVec[0].dataStr, dtype=np.float32) + data = data.reshape(1, 784) + fake.append(data) + + fig, ax = plt.subplots(n_cow, n_col, figsize=(10, 5)) + for digit, num in itertools.product(range(n_cow), range(n_col)): + ax[digit, num].get_xaxis().set_visible(False) + ax[digit, num].get_yaxis().set_visible(False) + + for i in range(n_image): + if (i + 1) % n_col == 0: + print("process ========= {}/200".format(i+1)) + digit = i // n_col + num = i % n_col + img = fake[i].reshape((28, 28)) + ax[digit, num].cla() + ax[digit, num].imshow(img * 127.5 + 127.5, cmap="gray") + + label = 'infer result' + fig.text(0.5, 0.01, label, ha='center') + fig.tight_layout() + plt.subplots_adjust(wspace=0.01, hspace=0.01) + print("===========saving image===========") + post_result_file = os.path.join(result_dir, 'result.png') + plt.savefig(post_result_file) + +if __name__ == "__main__": + args = parser_args() + args.stream_name = cfg.STREAM_NAME.encode("utf-8") + image_inference(args.pipeline_path, args.stream_name, args.infer_result_dir) diff --git a/research/cv/CGAN/infer/sdk/run.sh b/research/cv/CGAN/infer/sdk/run.sh new file mode 100644 index 0000000000000000000000000000000000000000..370ca1d5ce74e8acb1b3cf79b193e4e2fff6a17f --- /dev/null +++ b/research/cv/CGAN/infer/sdk/run.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# 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. + +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 PYTHONPATH=$PYTHONPATH:${MX_SDK_HOME}/python + +python3.7 main.py +exit 0 diff --git a/research/cv/CGAN/modelarts/start_train.py b/research/cv/CGAN/modelarts/start_train.py new file mode 100644 index 0000000000000000000000000000000000000000..b1a606bca48d4eb01db1d81ea58db70a379b45b1 --- /dev/null +++ b/research/cv/CGAN/modelarts/start_train.py @@ -0,0 +1,216 @@ +# 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. +# ============================================================================ +"""train""" +import os +import ast +import time +import datetime +import argparse +import numpy as np +import moxing as mox +from mindspore import nn +from mindspore import Tensor +from mindspore import context +from mindspore import load_checkpoint, save_checkpoint, load_param_into_net +from mindspore.context import ParallelMode +from mindspore.common import dtype as mstype +from mindspore.communication.management import init, get_group_size +from mindspore.train.serialization import export +import mindspore.ops as ops +from src.dataset import create_dataset +from src.model import Generator, Discriminator +from src.cell import GenWithLossCell, DisWithLossCell, TrainOneStepCell + + +def preLauch(): + """parse the console argument""" + parser = argparse.ArgumentParser(description='MindSpore cgan training') + parser.add_argument("--distribute", type=ast.literal_eval, default=False, + help="Run distribute, default is false.") + parser.add_argument('--device_id', type=int, default=0, + help='device id of Ascend (Default: 0)') + parser.add_argument('--ckpt_dir', type=str, + default='ckpt', help='checkpoint dir of CGAN') + parser.add_argument('--epochs', type=int, + default=50, help='epochs of CGAN for training') + parser.add_argument('--dataset', type=str, default='data/MNIST_Data/train', + help='dataset dir (default data/MNISt_Data/train)') + + # model art + parser.add_argument("--data_url", type=str, default="./dataset", help='real input file path') + parser.add_argument("--modelarts_data_dir", type=str, default="/cache/dataset", help='modelart input path') + parser.add_argument("--modelarts_result_dir", type=str, default="/cache/result", help='modelart output path.') + parser.add_argument("--obs_result_dir", type=str, default="./output", help='real output file path include .ckpt and .air') # modelarts -> obs + parser.add_argument("--modelarts_attrs", type=str, default="") + args = parser.parse_args() + + # if not exists 'imgs4', 'gif' or 'ckpt_dir', make it + if not os.path.exists(args.ckpt_dir): + os.mkdir(args.ckpt_dir) + # deal with the distribute analyze problem + if args.distribute: + device_id = args.device_id + context.set_context(save_graphs=False, + device_id=device_id, + device_target="Ascend", + mode=context.GRAPH_MODE) + init() + args.device_num = get_group_size() + context.set_auto_parallel_context(gradients_mean=True, + device_num=args.device_num, + parallel_mode=ParallelMode.DATA_PARALLEL) + else: + device_id = args.device_id + args.device_num = 1 + context.set_context(save_graphs=False, + mode=context.GRAPH_MODE, + device_target="Ascend") + context.set_context(device_id=device_id) + + print(os.system('env')) + return args + +def obs_data2modelarts(args): + """ + Copy train data from obs to modelarts by using moxing api. + """ + start = datetime.datetime.now() + print("===>>>Copy files from obs:{} to modelarts dir:{}".format(args.data_url, args.modelarts_data_dir)) + mox.file.copy_parallel(src_url=args.data_url, dst_url=args.modelarts_data_dir) + end = datetime.datetime.now() + print("===>>>Copy from obs to modelarts, time use:{}(s)".format((end - start).seconds)) + files = os.listdir(args.modelarts_data_dir) + print("===>>>Files:", files) + files = os.listdir(args.modelarts_data_dir + "/MNIST_Data/train") + print("===>>>Train files:", files) + files = os.listdir(args.modelarts_data_dir + "/MNIST_Data/test") + print("===>>>Test files:", files) + + if not mox.file.exists(args.obs_result_dir): + mox.file.make_dirs(args.obs_result_dir) + print("===>>>Copy files from obs:{} to modelarts dir:{}".format(args.obs_result_dir, args.modelarts_result_dir)) + mox.file.copy_parallel(src_url=args.obs_result_dir, dst_url=args.modelarts_result_dir) + files = os.listdir(args.modelarts_result_dir) + print("===>>>Files:", files) + +def modelarts_result2obs(args): + """ + Copy result data from modelarts to obs. + """ + obs_result_dir = args.obs_result_dir + if not mox.file.exists(obs_result_dir): + print(f"obs_result_dir[{obs_result_dir}] not exist!") + mox.file.make_dirs(obs_result_dir) + mox.file.copy_parallel(src_url='./ckpt', dst_url=os.path.join(obs_result_dir, 'ckpt')) + print("===>>>Copy Event or Checkpoint from modelarts dir: ./ckpt to obs:{}".format(obs_result_dir)) + mox.file.copy(src_url='CGAN.air', + dst_url=os.path.join(obs_result_dir, 'CGAN.air')) + files = os.listdir(obs_result_dir) + print("===>>>current Files:", files) + +def export_AIR(args): + """ + start modelarts export + """ + # training argument + input_dim = 100 + n_image = 200 + n_col = 20 + # create G Cell & D Cell + netG = Generator(input_dim) + + latent_code_eval = Tensor(np.random.randn(n_image, input_dim).astype(np.float32)) + + label_eval = np.zeros((n_image, 10), dtype=np.float32) + for i in range(n_image): + j = i // n_col + label_eval[i][j] = 1 + label_eval = Tensor(label_eval.astype(np.float32)) + + param_G = load_checkpoint("ckpt/CGAN.ckpt") + load_param_into_net(netG, param_G) + + export(netG, latent_code_eval, label_eval, file_name="CGAN", file_format="AIR") + print("CGAN exported") + +def main(): + # before training, we should set some arguments + args = preLauch() + + ## copy dataset from obs to modelarts + obs_data2modelarts(args) + args.train_path = args.modelarts_data_dir + "/MNIST_Data/train" + + # training argument + batch_size = 128 + input_dim = 100 + epoch_start = 0 + epoch_end = args.epochs + lr = 0.001 + + dataset = create_dataset(args.train_path, + flatten_size=28 * 28, + batch_size=batch_size, + num_parallel_workers=args.device_num) + + # create G Cell & D Cell + netG = Generator(input_dim) + netD = Discriminator(batch_size) + # create WithLossCell + netG_with_loss = GenWithLossCell(netG, netD) + netD_with_loss = DisWithLossCell(netG, netD) + # create optimizer cell + optimizerG = nn.Adam(netG.trainable_params(), lr) + optimizerD = nn.Adam(netD.trainable_params(), lr) + + net_train = TrainOneStepCell(netG_with_loss, + netD_with_loss, + optimizerG, + optimizerD) + + netG.set_train() + netD.set_train() + + data_size = dataset.get_dataset_size() + print("data-size", data_size) + print("=========== start training ===========") + for epoch in range(epoch_start, epoch_end): + step = 0 + start = time.time() + for data in dataset: + img = data[0] + label = data[1] + img = ops.Reshape()(img, (batch_size, 1, 28, 28)) + latent_code = Tensor(np.random.randn( + batch_size, input_dim), dtype=mstype.float32) + dout, gout = net_train(img, latent_code, label) + step += 1 + + if step % data_size == 0: + end = time.time() + pref = (end-start)*1000 / data_size + print("epoch {}, {:.3f} ms per step, d_loss is {:.4f}, g_loss is {:.4f}".format(epoch, + pref, dout.asnumpy(), + gout.asnumpy())) + + save_checkpoint(netG, './ckpt/CGAN.ckpt') + print("===========training success================") + ## start export air + export_AIR(args) + ## copy result from modelarts to obs + modelarts_result2obs(args) + +if __name__ == '__main__': + main() diff --git a/research/cv/CGAN/script/docker_start.sh b/research/cv/CGAN/script/docker_start.sh new file mode 100644 index 0000000000000000000000000000000000000000..7c1c17d85abfb5fdc2ae45ef6c8bde811541a93b --- /dev/null +++ b/research/cv/CGAN/script/docker_start.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# 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. +docker_image=$1 +data_dir=$2 +model_dir=$3 + +docker run -it --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 \ + -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ + -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \ + -v ${model_dir}:${model_dir} \ + -v ${data_dir}:${data_dir} \ + -v ~/ascend/log/npu/conf/slog/slog.conf:/var/log/npu/conf/slog/slog.conf \ + -v ~/ascend/log/npu/slog/:/var/log/npu/slog -v ~/ascend/log/npu/profiling/:/var/log/npu/profiling \ + -v ~/ascend/log/npu/dump/:/var/log/npu/dump -v ~/ascend/log/npu/:/usr/slog ${docker_image} \ + /bin/bash