从输入张量某个起始位置中提取指定大小的切片。
1 2 3 4 5 | struct SliceParam { SVector<int64_t> offsets; SVector<int64_t> size; uint8_t rsv[8] = {0}; }; |
成员名称 |
类型 |
默认值 |
描述 |
---|---|---|---|
offsets |
SVector<int64_t> |
- |
每个维度切片的起始位置。
|
size |
SVector<int64_t> |
- |
每个维度切片的大小。
|
rsv[8] |
uint8_t |
{0} |
预留参数。 |
参数 |
维度 |
数据类型 |
格式 |
描述 |
---|---|---|---|---|
x |
[dim_0, dim_1, ..., dim_n] |
float16/float/int8/bool/int32/uint32/bf16 |
ND |
输入tensor。 |
参数 |
维度 |
数据类型 |
格式 |
描述 |
---|---|---|---|---|
output |
和参数size表示的shape一样 |
float16/float/int8/bool/int32/uint32/bf16 |
ND |
输出tensor,维度的大小为size指定的大小。与x的数据类型相同。 |
x = [[ -78.9, 78.8, 32.22, 49.7, 82.8, 24.77], [ 72.2, 20.89, 55.16, 85.5, 72.8, 94.8], [ 11.36, -83.56, 65.94, -46.94, 72.44, 68.7]] offsets = [1, 2] size = [2, 4]
在第0维上,从下标为1开始切片长度为2。
在第1维上从下标为2开始向后切片长度为4 (2+4 <= 6)。
y.dim = [2, 4] y = [[ 55.1562, 85.5000, 72.8125, 94.8125], [ 65.9375, -46.9375, 72.4375, 68.6875]]
若size中的维度为-1, 表示自动推导输出shape。
前置条件和编译命令请参见算子调用示例。
场景:基础场景。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | #include <iostream> #include <vector> #include <numeric> #include "acl/acl.h" #include "atb/operation.h" #include "atb/types.h" #include "atb/atb_infer.h" #include "demo_util.h" using namespace atb; using namespace std; /** * @brief 准备atb::VariantPack中的所有输入tensor * @param contextPtr context指针 * @param stream stream * @param seqLenHost host侧tensor。序列长度向量,等于1时,为增量或全量;大于1时,为全量 * @param tokenOffsetHost host侧tensor。计算完成后的token偏移 * @param layerId layerId,取cache的kv中哪一个kv进行计算 * @return atb::SVector<atb::Tensor> atb::VariantPack中的输入tensor * @note 需要传入所有host侧tensor */ atb::SVector<atb::Tensor> PrepareInTensor(atb::Context *contextPtr, aclrtStream stream) { uint32_t dim0 = 3; uint32_t dim1 = 6; // 创建tensor0 std::vector<float> tensorzero{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; atb::Tensor tensorZero = CreateTensorFromVector(contextPtr, stream, tensorzero, ACL_FLOAT, aclFormat::ACL_FORMAT_ND, {dim0, dim1}); // 根据顺序将所有输入tensor放入SVector atb::SVector<atb::Tensor> inTensors = {tensorZero}; return inTensors; } /** * @brief 创建一个slice的Operation,并设置参数 * @return atb::Operation * 返回一个Operation指针 */ atb::Operation *PrepareOperation() { atb::infer::SliceParam sliceParam; sliceParam.offsets = {1, 2}; sliceParam.size = {2, 4}; atb::Operation *op = nullptr; CHECK_STATUS(atb::CreateOperation(sliceParam, &op)); return op; } int main(int argc, char **argv) { // 1.设置卡号、创建context、设置stream CHECK_STATUS(aclInit(nullptr)); int32_t deviceId = 0; CHECK_STATUS(aclrtSetDevice(deviceId)); atb::Context *context = nullptr; CHECK_STATUS(atb::CreateContext(&context)); void *stream = nullptr; CHECK_STATUS(aclrtCreateStream(&stream)); context->SetExecuteStream(stream); // Slice示例 atb::Operation *op = PrepareOperation(); // 准备输入张量 atb::VariantPack variantPack; variantPack.inTensors = PrepareInTensor(context, stream); // 放入输入tensor atb::Tensor tensorOut = CreateTensor(ACL_FLOAT, aclFormat::ACL_FORMAT_ND, {2, 4}); // 创建输出tensor variantPack.outTensors.push_back(tensorOut); // 放入输出tensor // 计算workspace大小 uint64_t workspaceSize = 0; CHECK_STATUS(op->Setup(variantPack, workspaceSize, context)); uint8_t *workspacePtr = nullptr; if (workspaceSize > 0) { CHECK_STATUS(aclrtMalloc((void **)(&workspacePtr), workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST)); } // execute阶段 op->Execute(variantPack, workspacePtr, workspaceSize, context); CHECK_STATUS(aclrtSynchronizeStream(stream)); // 流同步,等待device侧任务计算完成 // 释放内存 for (atb::Tensor &inTensor : variantPack.inTensors) { CHECK_STATUS(aclrtFree(inTensor.deviceData)); } if (workspaceSize > 0) { CHECK_STATUS(aclrtFree(workspacePtr)); } // 资源释放 CHECK_STATUS(atb::DestroyOperation(op)); // operation,对象概念,先释放 CHECK_STATUS(aclrtDestroyStream(stream)); CHECK_STATUS(atb::DestroyContext(context)); // context,全局资源,后释放 CHECK_STATUS((aclFinalize())); std::cout << "slice demo success!" << std::endl; return 0; } |