ACL,pyACL推理结果后续数据处理
收藏回复举报
ACL,pyACL推理结果后续数据处理
发表于2025-03-31 20:02:47
0 查看

pyacl推理结果后续处理比acl麻烦,因为pyacl使用python开发,而acl使用c++来开发,acl可以直接操作内存指针,所以在推理结束后可以直接利用指针获取数据,但是pyacl不行,需要做的事情也会比较多,下面我们来看看因该如何操作,才能得到最后的结果。

acl

1. 首先我们假设已经有了输出数据集aclmdlDataset *inferenceOutput(在推理过程中就已经创建好的),在此基础上,我们获取输出buffer

aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(inferenceOutput, 0);//以第0个输出作为例子

2. 接下来获取输出的大小和内存指针

void* dataBufferDev = aclGetDataBufferAddr(dataBuffer);
size_t bufferSize = aclGetDataBufferSizeV2(dataBuffer);

3. 最后一步将数据从device侧拷贝到host侧,如下

void* data = nullptr;
aclrtMemcpy(data, bufferSize, dataBufferDev, bufferSize, ACL_MEMCPY_DEVICE_TO_HOST);

接下来看看pyacl该如何操作

pyacl

1. 首先我们需要根据模型的输出创建0的numpy数组。形状和大小,还有数据类型需要根据每个输出来定。我们要用到
get_output_dims来获取每个输出的数组维度,

dims = acl.mdl.get_output_dims(model_desc, i)、
shape = tuple(dims[0]['dims'])

用到get_output_data_type来获取数组的数据类型,

datatype = acl.mdl.get_output_data_type(model_desc, i)

另外,还要用到get_output_size_by_index获取数组的大小,

size = acl.mdl.get_output_size_by_index(model_desc, i)

2. 接下来我们按照这三个数据创建numpy数组,他的形状就是上述的shape,数据类型就是datatype,那么我们需要按照以下方式创建数组

dims = acl.mdl.get_output_dims(model_desc, i)
shape = tuple(dims[0]['dims'])
datatype = acl.mdl.get_output_data_type(model_desc, i)
size = acl.mdl.get_output_size_by_index(model_desc, i)
if datatype == const.ACL_FLOAT:
    np_type = np.float32
    output_tensor = np.zeros(
        size // 4, dtype=np_type).reshape(shape)
elif datatype == const.ACL_DOUBLE:
    np_type = np.float64
    output_tensor = np.zeros(
        size // 8, dtype=np_type).reshape(shape)
elif datatype == const.ACL_INT64:
    np_type = np.int64
    output_tensor = np.zeros(
        size // 8, dtype=np_type).reshape(shape)
elif datatype == const.ACL_UINT64:
    np_type = np.uint64
    output_tensor = np.zeros(
        size // 8, dtype=np_type).reshape(shape)
elif datatype == const.ACL_INT32:
    np_type = np.int32
    output_tensor = np.zeros(
        size // 4, dtype=np_type).reshape(shape)
elif datatype == const.ACL_UINT32:
    np_type = np.uint32
    output_tensor = np.zeros(
        size // 4, dtype=np_type).reshape(shape)
elif datatype == const.ACL_FLOAT16:
    np_type = np.float16
    output_tensor = np.zeros(
        size // 2, dtype=np_type).reshape(shape)
elif datatype == const.ACL_INT16:
    np_type = np.int16
    output_tensor = np.zeros(
        size // 2, dtype=np_type).reshape(shape)
elif datatype == const.ACL_UINT16:
    np_type = np.uint16
    output_tensor = np.zeros(
        size // 2, dtype=np_type).reshape(shape)
elif datatype == const.ACL_INT8:
    np_type = np.int8
    output_tensor = np.zeros(
        size, dtype=np_type).reshape(shape)
elif datatype == const.ACL_BOOL or datatype == const.ACL_UINT8:
    np_type = np.uint8
    output_tensor = np.zeros(
        size, dtype=np_type).reshape(shape)
else:
    print("Unspport model output datatype ", datatype)
    return None

这里出现size // 4,size // 8等是因为不同的数据类型占用的内存大小不一样,比如float64,每个数占用8个字节,所以把数据平铺开来就是有size // 8的长度。其他类似。然后转换成c语言能使用的数据。

out_bytes_data = output_tensor.tobytes()
tensor_ptr = acl.util.bytes_to_ptr(out_bytes_data)

3. 接下来读取输出数据大小以及内存地址,

buf = acl.mdl.get_dataset_buffer(output_dataset, i)
data = acl.get_data_buffer_addr(buf)
size = int(acl.get_data_buffer_size(buf))
output_ptr = tensor_list[i]["ptr"]
output_data = tensor_list[i]['tensor']

4. 最后考入将数据拷贝到之前创建的数组中,并读取结果,output_data

ret = acl.rt.memcpy(output_ptr, data_size, data, size, copy_policy)
output_data = np.frombuffer(output_data, dtype=tensor_list[i]['dtype']).reshape(tensor_list[i]["shape"])

相比之下,pyacl推理结果后续处理比acl麻烦,区别在于c++可以直接操作指针而python不行。

我要发帖子