utils.cpp 9.72 KB
#include "utils.h"
#include <map>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <dirent.h>
#include <vector>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "sy_errorinfo.h"
#include "acl/acl.h"
#include "acl/ops/acl_dvpp.h"
#include <algorithm>
#include <math.h>

using namespace std;
aclrtRunMode Utils::runMode_ = ACL_DEVICE;

void* Utils::CopyDataHostToDvpp(void* data, int size) {
    void* buffer = nullptr;
    auto aclRet = acldvppMalloc(&buffer, size);
    //debug====================================================
    aclrtMemset(buffer,size, 0, size);
    //debug end================================================
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("acl malloc dvpp data failed, dataSize=%u, ret=%d",
        size, aclRet);
        return nullptr;
    }
    // INFO_LOG("malloc dvpp memory size %d ok", size);
    // copy input to device memory
    aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_HOST_TO_DEVICE);
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("acl memcpy data to dvpp failed, size %u, error %d", size, aclRet);
        acldvppFree(buffer);
        return nullptr;
    }
    //INFO_LOG("copy data to dvpp ok");

    return buffer;
}

void* Utils::CopyDataDeviceToDvpp(void* data, int size) {
    void* buffer = nullptr;
    auto aclRet = acldvppMalloc(&buffer, size);
    //debug====================================================
    aclrtMemset(buffer,size, 0, size);
    //debug end================================================
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("acl malloc dvpp data failed, dataSize=%u, ret=%d",
        size, aclRet);
        return nullptr;
    }
    // INFO_LOG("malloc dvpp memory size %d ok", size);
    // copy input to device memory
    aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_DEVICE_TO_DEVICE);
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("acl memcpy data to dvpp failed, size %u, error %d", size, aclRet);
        acldvppFree(buffer);
        return nullptr;
    }
    //INFO_LOG("copy data to dvpp ok");

    return buffer;
}


int Utils::CopysyImageDataToDvpp(ImageData& imageDevice, sy_img srcImage) {
    aclError ret = aclrtGetRunMode(&runMode_);
    if (ret != ACL_SUCCESS) {
        ERROR_LOG("acl get run mode failed");
        return SY_FAILED;
    }

    void* buffer = nullptr;
    //230316 ascend310p兼容=================================================
    uint32_t alignWidth = 0, alignHeight = 0;
    auto socVersion = aclrtGetSocName();
    if (strncmp(socVersion, "Ascend310P3", sizeof("Ascend310P3") - 1) == 0) {
        alignWidth = ALIGN_UP64(srcImage.w_); // 64-byte alignment
        alignHeight = ALIGN_UP16(srcImage.h_); // 16-byte alignment
    } else {
        alignWidth = ALIGN_UP128(srcImage.w_); // 128-byte alignment
        alignHeight = ALIGN_UP16(srcImage.h_); // 16-byte alignment
    }
    if (alignWidth == 0 || alignHeight == 0) {
        ERROR_LOG("Input image width %d or height %d invalid",srcImage.w_, srcImage.h_);
        return SY_FAILED;
    }
    //=====================================================================
    uint32_t size = YUV420SP_SIZE(alignWidth, alignHeight);
    // cout << srcImage.w_ << " " << srcImage.h_ << " "<< alignWidth << " "<< alignHeight << " " << size << endl;
    if (runMode_ == ACL_HOST){
        // printf("1111111111\n");
        buffer = Utils::CopyDataHostToDvpp(srcImage.data_, size);
        if (buffer == nullptr) {
            ERROR_LOG("Copy image to device failed");
            return SY_FAILED;
        }
    }
    else{
        // printf("2222222222\n");
        buffer = Utils::CopyDataDeviceToDvpp(srcImage.data_, size);
        if (buffer == nullptr) {
            ERROR_LOG("Copy image to device failed");
            return SY_FAILED;
        }
    }

    imageDevice.width = srcImage.w_;
    imageDevice.height = srcImage.h_;
    imageDevice.alignWidth = alignWidth;
    imageDevice.alignHeight = alignHeight;
    imageDevice.size = size;
    imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { acldvppFree((void *)p); });
    
    return SY_SUCCESS;
}

int Utils::CopyImageDataToDvpp(ImageData& imageDevice, ImageData srcImage) {
    aclError ret = aclrtGetRunMode(&runMode_);
    if (ret != ACL_SUCCESS) {
        ERROR_LOG("acl get run mode failed");
        return SY_FAILED;
    }

    void* buffer = nullptr;
    if (runMode_ == ACL_HOST){
        buffer = Utils::CopyDataHostToDvpp(srcImage.data.get(), srcImage.size);
        if (buffer == nullptr) {
            ERROR_LOG("Copy image to device failed");
            return SY_FAILED;
        }
    }
    else{
        buffer = Utils::CopyDataDeviceToDvpp(srcImage.data.get(), srcImage.size);
        if (buffer == nullptr) {
            ERROR_LOG("Copy image to device failed");
            return SY_FAILED;
        }
    }

    imageDevice.width = srcImage.width;
    imageDevice.height = srcImage.height;
    imageDevice.size = srcImage.size;
    imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { acldvppFree((void *)p); });
    return SY_SUCCESS;
}

void* Utils::CopyDataDeviceToLocal(void* deviceData, uint32_t dataSize) {
    uint8_t* buffer = new uint8_t[dataSize];
    if (buffer == nullptr) {
        ERROR_LOG("New malloc memory failed");
        return nullptr;
    }

    aclError aclRet = aclrtMemcpy(buffer, dataSize, deviceData, dataSize, ACL_MEMCPY_DEVICE_TO_HOST);
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("Copy device data to local failed, aclRet is %d", aclRet);
        delete[](buffer);
        return nullptr;
    }

    return (void*)buffer;
}

void* Utils::CopyDataToDevice(void* data, uint32_t dataSize, aclrtMemcpyKind policy) {
    void* buffer = nullptr;
    aclError aclRet = aclrtMalloc(&buffer, dataSize, ACL_MEM_MALLOC_HUGE_FIRST);
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("malloc device data buffer failed, aclRet is %d", aclRet);
        return nullptr;
    }

    aclRet = aclrtMemcpy(buffer, dataSize, data, dataSize, policy);
    if (aclRet != ACL_SUCCESS) {
        ERROR_LOG("Copy data to device failed, aclRet is %d", aclRet);
        (void)aclrtFree(buffer);
        return nullptr;
    }

    return buffer;
}

void* Utils::CopyDataDeviceToDevice(void* deviceData, uint32_t dataSize) {
    return CopyDataToDevice(deviceData, dataSize, ACL_MEMCPY_DEVICE_TO_DEVICE);
}

void* Utils::CopyDataHostToDevice(void* deviceData, uint32_t dataSize) {
    return CopyDataToDevice(deviceData, dataSize, ACL_MEMCPY_HOST_TO_DEVICE);
}

int Utils::CopyImageDataToDevice(ImageData& imageDevice, ImageData srcImage, aclrtRunMode mode) {
    void * buffer;
    if (mode == ACL_HOST)
        buffer = Utils::CopyDataHostToDevice(srcImage.data.get(), srcImage.size);
    else
        buffer = Utils::CopyDataDeviceToDevice(srcImage.data.get(), srcImage.size);

    if (buffer == nullptr) {
        ERROR_LOG("Copy image to device failed");
        return SY_FAILED;
    }

    imageDevice.width = srcImage.width;
    imageDevice.height = srcImage.height;
    imageDevice.size = srcImage.size;
    imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { aclrtFree((void *)p); });

    return SY_SUCCESS;
}


int Utils::ReadImageFile(ImageData& image, std::string fileName) {
    struct stat sBuf;
    int fileStatus = stat(fileName.data(), &sBuf);
    if (fileStatus == -1) {
        ERROR_LOG("failed to get file");
        return SY_FAILED;
    }
    if (S_ISREG(sBuf.st_mode) == 0) {
        ERROR_LOG("%s is not a file, please enter a file", fileName.c_str());
        return SY_FAILED;
    }
    std::ifstream binFile(fileName, std::ifstream::binary);
    if (binFile.is_open() == false) {
        ERROR_LOG("open file %s failed", fileName.c_str());
        return SY_FAILED;
    }

    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 SY_FAILED;
    }

    binFile.seekg(0, binFile.beg);

    uint8_t* binFileBufferData = new(std::nothrow) uint8_t[binFileBufferLen];
    if (binFileBufferData == nullptr) {
        ERROR_LOG("malloc binFileBufferData failed");
        binFile.close();
        return SY_FAILED;
    }
    binFile.read((char *)binFileBufferData, binFileBufferLen);
    binFile.close();

    int32_t ch = 0;
    acldvppJpegGetImageInfo(binFileBufferData, binFileBufferLen,
              &(image.width), &(image.height), &ch);
    image.data.reset(binFileBufferData, [](uint8_t* p) { delete[](p); });
    image.size = binFileBufferLen;

    return SY_SUCCESS;
}


float Utils::sigmoid(float val){
    return 1.0/(1.0+exp(-val));
}


// double Power(double base, int n) {
//     double res = 1,curr = base;
//     int exponent;
//     if(n>0){
//         exponent = n;
//     }else if(n==0){
//         return 1;
//     }else{
//         exponent = -n;
//     }
//     while(exponent!=0){
//         if((exponent&1)==1)
//             res*=curr;
//         curr*=curr;// 翻倍
//         exponent>>=1;// 右移一位
//     }
//     return n>=0?res:(1/res);
// }


// float Utils::sigmoid1(float val){
//     return 1.0/(1.0+Power(exp(1.),-val));
// }

float FastExp(float x) {
    float d;
    //将尾数后32位抹零
    *(reinterpret_cast<short*>(&d) + 0) = 0;
    //计算指数位
    *(reinterpret_cast<short*>(&d) + 1) = static_cast<short>(184 * x + (16256-7));
    return d;
}

float Utils::FastSigmoid(float x) {
    // float x_ = x / 4096.;  //int32
    float x_ = x;
    return 1. / (FastExp(0 - x_) + 1.);
}