10
csrc/attention/store_kv_block_metadata/CMakeLists.txt
Normal file
10
csrc/attention/store_kv_block_metadata/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# ---------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
# CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
# Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See LICENSE in the root of the software repository for the full text of the License.
|
||||
# ---------------------------------------------------------------------------------------------------------
|
||||
add_modules_sources_aicpu(OPTYPE store_kv_block ACLNNTYPE aclnn)
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file aclnn_store_kv_block_metadata.cpp
|
||||
* \brief AClnn interface for StoreKvBlockMetadata operator
|
||||
*/
|
||||
|
||||
#include "aclnn_store_kv_block_metadata.h"
|
||||
#include "l0_store_kv_block_metadata.h"
|
||||
#include "aclnn_kernels/contiguous.h"
|
||||
#include "aclnn_kernels/reshape.h"
|
||||
#include "aclnn/aclnn_base.h"
|
||||
#include "aclnn_kernels/common/op_error_check.h"
|
||||
#include "opdev/common_types.h"
|
||||
#include "opdev/data_type_utils.h"
|
||||
#include "opdev/format_utils.h"
|
||||
#include "opdev/op_dfx.h"
|
||||
#include "opdev/op_executor.h"
|
||||
#include "opdev/op_log.h"
|
||||
#include "opdev/tensor_view_utils.h"
|
||||
#include "opdev/make_op_executor.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
aclnnStatus aclnnStoreKvBlockMetadataGetWorkspaceSize(
|
||||
const aclTensor *slotMapping,
|
||||
const aclTensor *groupLen,
|
||||
const aclTensor *groupKeyIdx,
|
||||
const aclTensor *groupKeyCacheIdx,
|
||||
int64_t blockSize,
|
||||
uint64_t *workspaceSize,
|
||||
aclOpExecutor **executor)
|
||||
{
|
||||
L2_DFX_PHASE_1(aclnnStoreKvBlockMetadata,
|
||||
DFX_IN(slotMapping, blockSize),
|
||||
DFX_OUT(groupLen, groupKeyIdx, groupKeyCacheIdx));
|
||||
|
||||
auto uniqueExecutor = CREATE_EXECUTOR();
|
||||
CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
|
||||
|
||||
// basic parameter checks
|
||||
CHECK_RET(slotMapping != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
CHECK_RET(groupLen != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
CHECK_RET(groupKeyIdx != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
CHECK_RET(groupKeyCacheIdx != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
CHECK_RET(blockSize > 0, ACLNN_ERR_PARAM_INVALID);
|
||||
|
||||
auto slotMappingContiguous = l0op::Contiguous(slotMapping, uniqueExecutor.get());
|
||||
CHECK_RET(slotMappingContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
|
||||
auto ret = l0op::StoreKvBlockMetadata(slotMappingContiguous, groupLen, groupKeyIdx, groupKeyCacheIdx,blockSize,
|
||||
uniqueExecutor.get());
|
||||
CHECK_RET(ret != nullptr, ACLNN_ERR_INNER_NULLPTR);
|
||||
|
||||
*workspaceSize = 0;
|
||||
uniqueExecutor.ReleaseTo(executor);
|
||||
return ACLNN_SUCCESS;
|
||||
}
|
||||
|
||||
__attribute__((visibility("default"))) aclnnStatus aclnnStoreKvBlockMetadata(void *workspace, uint64_t workspaceSize,
|
||||
aclOpExecutor *executor, aclrtStream stream)
|
||||
{
|
||||
L2_DFX_PHASE_2(aclnnStoreKvBlockMetadata);
|
||||
return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
#ifndef ACLNN_STORE_KV_BLOCK_METADATA_H
|
||||
#define ACLNN_STORE_KV_BLOCK_METADATA_H
|
||||
|
||||
#include "aclnn/aclnn_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((visibility("default"))) aclnnStatus aclnnStoreKvBlockMetadataGetWorkspaceSize(
|
||||
const aclTensor *slotMapping,
|
||||
const aclTensor *groupLen,
|
||||
const aclTensor *groupKeyIdx,
|
||||
const aclTensor *groupKeyCacheIdx,
|
||||
int64_t blockSize,
|
||||
uint64_t *workspaceSize,
|
||||
aclOpExecutor **executor);
|
||||
|
||||
__attribute__((visibility("default"))) aclnnStatus aclnnStoreKvBlockMetadata(void *workspace, uint64_t workspaceSize,
|
||||
aclOpExecutor *executor, aclrtStream stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ACLNN_STORE_KV_BLOCK_METADATA_H
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file l0_store_kv_block_metadata.cpp
|
||||
* \brief L0 interface for StoreKvBlockMetadata, adds AICPU task to launcher list
|
||||
*/
|
||||
|
||||
#include "l0_store_kv_block_metadata.h"
|
||||
#include "opdev/aicpu/aicpu_task.h"
|
||||
#include "opdev/make_op_executor.h"
|
||||
#include "opdev/op_def.h"
|
||||
#include "opdev/op_dfx.h"
|
||||
#include "opdev/op_executor.h"
|
||||
#include "opdev/op_log.h"
|
||||
#include "opdev/shape_utils.h"
|
||||
|
||||
using namespace op;
|
||||
namespace l0op {
|
||||
OP_TYPE_REGISTER(StoreKvBlockMetadata);
|
||||
|
||||
const aclTensor *StoreKvBlockMetadata(
|
||||
const aclTensor *slotMapping,
|
||||
const aclTensor *groupLen,
|
||||
const aclTensor *groupKeyIdx,
|
||||
const aclTensor *groupKeyCacheIdx,
|
||||
int64_t blockSize,
|
||||
aclOpExecutor *executor)
|
||||
{
|
||||
L0_DFX(StoreKvBlockMetadata, slotMapping, groupLen, groupKeyIdx, groupKeyCacheIdx, blockSize);
|
||||
|
||||
static internal::AicpuTaskSpace space("StoreKvBlockMetadata");
|
||||
|
||||
auto ret = ADD_TO_LAUNCHER_LIST_AICPU(
|
||||
StoreKvBlockMetadata,
|
||||
OP_ATTR_NAMES({"block_size"}),
|
||||
OP_INPUT(slotMapping,groupLen, groupKeyIdx, groupKeyCacheIdx),
|
||||
OP_ATTR(blockSize));
|
||||
OP_CHECK(ret == ACL_SUCCESS,
|
||||
OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "StoreKvBlockMetadata"
|
||||
" ADD_TO_LAUNCHER_LIST_AICPU failed."),
|
||||
return nullptr);
|
||||
return groupLen;
|
||||
}
|
||||
|
||||
} // namespace l0op
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
#ifndef L0_STORE_KV_BLOCK_METADATA_H
|
||||
#define L0_STORE_KV_BLOCK_METADATA_H
|
||||
|
||||
#include "opdev/op_executor.h"
|
||||
|
||||
namespace l0op {
|
||||
const aclTensor* StoreKvBlockMetadata(
|
||||
const aclTensor* slotMapping,
|
||||
const aclTensor* groupLen,
|
||||
const aclTensor* groupKeyIdx,
|
||||
const aclTensor* groupKeyCacheIdx,
|
||||
int64_t blockSize,
|
||||
aclOpExecutor* executor);
|
||||
} // namespace l0op
|
||||
|
||||
#endif // L0_STORE_KV_BLOCK_METADATA_H
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file store_kv_block_metadata_proto.h
|
||||
* \brief Operator registration for StoreKvBlockMetadata
|
||||
*/
|
||||
#ifndef STORE_KV_BLOCK_METADATA_PROTO_H
|
||||
#define STORE_KV_BLOCK_METADATA_PROTO_H
|
||||
|
||||
#include "graph/operator_reg.h"
|
||||
#include "graph/types.h"
|
||||
|
||||
namespace ge {
|
||||
|
||||
REG_OP(StoreKvBlockMetadata)
|
||||
.INPUT(slot_mapping, TensorType({DT_INT32}))
|
||||
.INPUT(group_len, TensorType({DT_INT32}))
|
||||
.INPUT(group_key_idx, TensorType({DT_INT32}))
|
||||
.INPUT(group_key_cache_idx, TensorType({DT_INT32}))
|
||||
.REQUIRED_ATTR(block_size, Int)
|
||||
.OP_END_FACTORY_REG(StoreKvBlockMetadata)
|
||||
|
||||
} // namespace ge
|
||||
|
||||
#endif // STORE_KV_BLOCK_METADATA_PROTO_H
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file store_kv_block_metadata_infershape.cpp
|
||||
* \brief InferShape implementation for StoreKvBlockMetadata
|
||||
*/
|
||||
#include <register/op_impl_registry.h>
|
||||
|
||||
using namespace ge;
|
||||
|
||||
namespace ops {
|
||||
|
||||
static constexpr int DIM_0 = 0;
|
||||
|
||||
static ge::graphStatus InferShape4StoreKvBlockMetadata(gert::InferShapeContext* context)
|
||||
{
|
||||
// All tensors are inputs now; nothing to infer for outputs.
|
||||
// Validate that slot_mapping (input 0) exists.
|
||||
auto inputShape = context->GetInputShape(DIM_0);
|
||||
if (inputShape == nullptr) {
|
||||
return GRAPH_FAILED;
|
||||
}
|
||||
return GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
static graphStatus InferDataType4StoreKvBlockMetadata(gert::InferDataTypeContext* context)
|
||||
{
|
||||
return GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
IMPL_OP_INFERSHAPE(StoreKvBlockMetadata)
|
||||
.InferShape(InferShape4StoreKvBlockMetadata)
|
||||
.InferDataType(InferDataType4StoreKvBlockMetadata);
|
||||
|
||||
} // namespace ops
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You should not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file store_kv_block_metadata_aicpu.cpp
|
||||
* \brief AICPU kernel implementation for StoreKvBlockMetadata
|
||||
*
|
||||
* Ports the logic from store_kv_block_pre: groups contiguous slot_mapping entries
|
||||
* that belong to the same block, producing group_len / group_key_idx / group_key_cache_idx.
|
||||
*/
|
||||
|
||||
#include "log.h"
|
||||
#include "status.h"
|
||||
#include <cstring>
|
||||
#include "store_kv_block_metadata_aicpu.h"
|
||||
|
||||
namespace aicpu {
|
||||
|
||||
uint32_t StoreKvBlockMetadataCpuKernel::Compute(CpuKernelContext &ctx)
|
||||
{
|
||||
bool success = Prepare(ctx);
|
||||
if (!success) {
|
||||
return KERNEL_STATUS_PARAM_INVALID;
|
||||
}
|
||||
return GenMetaData() ? KERNEL_STATUS_OK : KERNEL_STATUS_PARAM_INVALID;
|
||||
}
|
||||
|
||||
bool StoreKvBlockMetadataCpuKernel::Prepare(CpuKernelContext &ctx)
|
||||
{
|
||||
// inputs
|
||||
slotMapping_ = ctx.Input(static_cast<uint32_t>(ParamId::slotMapping));
|
||||
groupLen_ = ctx.Input(static_cast<uint32_t>(ParamId::groupLen));
|
||||
groupKeyIdx_ = ctx.Input(static_cast<uint32_t>(ParamId::groupKeyIdx));
|
||||
groupKeyCacheIdx_ = ctx.Input(static_cast<uint32_t>(ParamId::groupKeyCacheIdx));
|
||||
|
||||
// attribute
|
||||
auto attr = ctx.GetAttr("block_size");
|
||||
if (attr == nullptr) {
|
||||
KERNEL_LOG_ERROR("attr block_size is null");
|
||||
return false;
|
||||
}
|
||||
blockSize_ = static_cast<int32_t>(attr->GetInt());
|
||||
if (blockSize_ <= 0) {
|
||||
KERNEL_LOG_ERROR("block_size must be positive, got %d", blockSize_);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StoreKvBlockMetadataCpuKernel::GenMetaData()
|
||||
{
|
||||
if (slotMapping_ == nullptr || slotMapping_->GetData() == nullptr) {
|
||||
KERNEL_LOG_ERROR("slot_mapping is empty");
|
||||
return false;
|
||||
}
|
||||
if (groupLen_ == nullptr || groupLen_->GetData() == nullptr ||
|
||||
groupKeyIdx_ == nullptr || groupKeyIdx_->GetData() == nullptr ||
|
||||
groupKeyCacheIdx_ == nullptr || groupKeyCacheIdx_->GetData() == nullptr) {
|
||||
KERNEL_LOG_ERROR("input tensor is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t *slotMappingData = static_cast<int32_t *>(slotMapping_->GetData());
|
||||
int32_t *groupLenData = static_cast<int32_t *>(groupLen_->GetData());
|
||||
int32_t *groupKeyIdxData = static_cast<int32_t *>(groupKeyIdx_->GetData());
|
||||
int32_t *groupKeyCacheIdxData = static_cast<int32_t *>(groupKeyCacheIdx_->GetData());
|
||||
|
||||
// total elements in slot_mapping (1-D tensor)
|
||||
int64_t slotMappingLen = slotMapping_->GetTensorShape()->GetDimSize(0);
|
||||
|
||||
// total capacity of output tensors (1-D, same shape as input)
|
||||
int64_t outCapacity = groupLen_->GetTensorShape()->GetDimSize(0);
|
||||
|
||||
int32_t idxSlotmap = 0;
|
||||
int32_t idxGroups = 0;
|
||||
|
||||
while (idxSlotmap < slotMappingLen) {
|
||||
// Skip dirty values (negative slots)
|
||||
int32_t cacheSlot = slotMappingData[idxSlotmap];
|
||||
if (cacheSlot < 0) {
|
||||
idxSlotmap++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t blockId = cacheSlot / blockSize_;
|
||||
|
||||
// Record group start: source index and destination cache index
|
||||
groupKeyIdxData[idxGroups] = idxSlotmap;
|
||||
groupKeyCacheIdxData[idxGroups] = cacheSlot;
|
||||
|
||||
// Find the end of consecutive slots within the same block
|
||||
int32_t groupEndIdx = idxSlotmap;
|
||||
while (groupEndIdx + 1 < slotMappingLen
|
||||
&& slotMappingData[groupEndIdx + 1] / blockSize_ == blockId
|
||||
&& slotMappingData[groupEndIdx + 1] == slotMappingData[groupEndIdx] + 1) {
|
||||
groupEndIdx++;
|
||||
}
|
||||
groupEndIdx++;
|
||||
|
||||
groupLenData[idxGroups] = groupEndIdx - idxSlotmap;
|
||||
|
||||
idxSlotmap = groupEndIdx;
|
||||
idxGroups++;
|
||||
}
|
||||
|
||||
// 0 fill the remaining output entries. store_kv_block kernel reads groupLen as uint32_t,
|
||||
// so negative fillers would be interpreted as huge positive values and bypass the
|
||||
// `groupLen <= 0` guard, causing out-of-range MTE writes. Use 0 so that guard works.
|
||||
if (idxGroups < outCapacity) {
|
||||
std::memset(groupLenData + idxGroups, 0,
|
||||
static_cast<size_t>(outCapacity - idxGroups) * sizeof(int32_t));
|
||||
std::memset(groupKeyIdxData + idxGroups, 0,
|
||||
static_cast<size_t>(outCapacity - idxGroups) * sizeof(int32_t));
|
||||
std::memset(groupKeyCacheIdxData + idxGroups, 0,
|
||||
static_cast<size_t>(outCapacity - idxGroups) * sizeof(int32_t));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
static const char *kernelType = "StoreKvBlockMetadata";
|
||||
REGISTER_CPU_KERNEL(kernelType, StoreKvBlockMetadataCpuKernel);
|
||||
} // namespace
|
||||
|
||||
} // namespace aicpu
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file store_kv_block_metadata_aicpu.h
|
||||
* \brief AICPU kernel for StoreKvBlockMetadata: groups contiguous slot_mapping entries
|
||||
*/
|
||||
|
||||
#ifndef STORE_KV_BLOCK_METADATA_AICPU_H
|
||||
#define STORE_KV_BLOCK_METADATA_AICPU_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "cpu_context.h"
|
||||
#include "cpu_kernel.h"
|
||||
#include "cpu_tensor.h"
|
||||
|
||||
namespace aicpu {
|
||||
|
||||
class StoreKvBlockMetadataCpuKernel : public CpuKernel {
|
||||
public:
|
||||
StoreKvBlockMetadataCpuKernel() = default;
|
||||
~StoreKvBlockMetadataCpuKernel() = default;
|
||||
uint32_t Compute(CpuKernelContext &ctx) override;
|
||||
|
||||
private:
|
||||
bool Prepare(CpuKernelContext &ctx);
|
||||
bool GenMetaData();
|
||||
|
||||
private:
|
||||
// input tensor
|
||||
Tensor *slotMapping_ = nullptr;
|
||||
Tensor *groupLen_ = nullptr;
|
||||
Tensor *groupKeyIdx_ = nullptr;
|
||||
Tensor *groupKeyCacheIdx_ = nullptr;
|
||||
// attribute
|
||||
int32_t blockSize_ = 0;
|
||||
|
||||
private:
|
||||
enum class ParamId : uint32_t {
|
||||
// input
|
||||
slotMapping = 0,
|
||||
groupLen = 1,
|
||||
groupKeyIdx = 2,
|
||||
groupKeyCacheIdx = 3,
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace aicpu
|
||||
|
||||
#endif // STORE_KV_BLOCK_METADATA_AICPU_H
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"StoreKvBlockMetadata":{
|
||||
"opInfo":{
|
||||
"computeCost":"100",
|
||||
"engine":"DNN_VM_AICPU",
|
||||
"flagAsync":"False",
|
||||
"flagPartial":"False",
|
||||
"functionName":"RunCpuKernel",
|
||||
"kernelSo":"libtransformer_aicpu_kernels.so",
|
||||
"opKernelLib":"CUSTAICPUKernel",
|
||||
"userDefined":"True",
|
||||
"workspaceSize":"100"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
||||
*
|
||||
* 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 STORE_KV_BLOCK_METADATA_TORCH_ADPT_H
|
||||
#define STORE_KV_BLOCK_METADATA_TORCH_ADPT_H
|
||||
// #include "aclnn_torch_adapter/op_api_common.h"
|
||||
|
||||
namespace vllm_ascend {
|
||||
|
||||
// Compute grouping metadata (group_len / group_key_idx / group_key_cache_idx)
|
||||
// for slot_mapping on AICPU. The AICPU kernel reads slot_mapping directly from
|
||||
// device memory, so the host-side slot_mapping_list is no longer needed.
|
||||
//
|
||||
// Outputs are pre-allocated with the same length as slot_mapping and zero-filled
|
||||
// by the kernel for unused entries. The caller can detect the actual group count
|
||||
// by scanning for the first zero group_len entry.
|
||||
void store_kv_block_metadata(
|
||||
const at::Tensor &slot_mapping_npu,
|
||||
const at::Tensor &group_len,
|
||||
const at::Tensor &group_key_idx,
|
||||
const at::Tensor &group_key_cache_idx,
|
||||
int64_t block_size)
|
||||
{
|
||||
TORCH_CHECK(slot_mapping_npu.numel() > 0, "Tensor slot_mapping_npu is empty.");
|
||||
TORCH_CHECK(block_size > 0, "block_size must be positive, but got ", block_size);
|
||||
|
||||
EXEC_NPU_CMD(aclnnStoreKvBlockMetadata,
|
||||
slot_mapping_npu,
|
||||
group_len,
|
||||
group_key_idx,
|
||||
group_key_cache_idx,
|
||||
block_size);
|
||||
}
|
||||
|
||||
} // namespace vllm_ascend
|
||||
|
||||
#endif // STORE_KV_BLOCK_METADATA_TORCH_ADPT_H
|
||||
Reference in New Issue
Block a user