* 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.
*/
#include <cstdint>
#include <cmath>
#include <cstdio>
#include <vector>
#include "acl/acl.h"
#include "vector_add_kernel.h"
#define CHECK_ERROR(ret) \
if ((ret) != ACL_SUCCESS) { \
printf("Error at line %d, ret = %d\n", __LINE__, static_cast<int32_t>(ret)); \
return -1; \
}
namespace {
constexpr uint32_t kElementCount = 8;
constexpr float kTolerance = 1e-5f;
}
int main()
{
const int32_t deviceId = 0;
const uint32_t blockDim = 1;
const size_t bufferSize = kElementCount * sizeof(float);
const float alpha = 1.0f;
aclrtStream stream = nullptr;
float* srcADevice = nullptr;
float* srcBDevice = nullptr;
float* dstDevice = nullptr;
const std::vector<float> srcAHost = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
const std::vector<float> srcBHost = {0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f};
std::vector<float> dstHost(kElementCount, 0.0f);
CHECK_ERROR(aclInit(nullptr));
printf("ACL init successfully\n");
CHECK_ERROR(aclrtSetDevice(deviceId));
printf("Set device %d successfully\n", deviceId);
CHECK_ERROR(aclrtCreateStream(&stream));
printf("Create stream successfully\n");
CHECK_ERROR(aclrtMalloc(reinterpret_cast<void**>(&srcADevice), bufferSize, ACL_MEM_MALLOC_HUGE_FIRST));
CHECK_ERROR(aclrtMalloc(reinterpret_cast<void**>(&srcBDevice), bufferSize, ACL_MEM_MALLOC_HUGE_FIRST));
CHECK_ERROR(aclrtMalloc(reinterpret_cast<void**>(&dstDevice), bufferSize, ACL_MEM_MALLOC_HUGE_FIRST));
printf("Allocate device buffers successfully\n");
CHECK_ERROR(aclrtMemcpy(srcADevice, bufferSize, srcAHost.data(), bufferSize, ACL_MEMCPY_HOST_TO_DEVICE));
CHECK_ERROR(aclrtMemcpy(srcBDevice, bufferSize, srcBHost.data(), bufferSize, ACL_MEMCPY_HOST_TO_DEVICE));
printf("Copy input vectors to device successfully\n");
printf("Input vectors:\n");
printf(
" self: [%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f]\n", srcAHost[0], srcAHost[1], srcAHost[2],
srcAHost[3], srcAHost[4], srcAHost[5], srcAHost[6], srcAHost[7]);
printf(
" other: [%.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f, %.1f]\n", srcBHost[0], srcBHost[1], srcBHost[2],
srcBHost[3], srcBHost[4], srcBHost[5], srcBHost[6], srcBHost[7]);
printf(" alpha: %.1f\n", alpha);
CHECK_ERROR(VectorAddDo(blockDim, stream, srcADevice, srcBDevice, dstDevice, alpha, kElementCount));
printf("Custom AscendC kernel <<<>>> call successfully\n");
CHECK_ERROR(aclrtSynchronizeStream(stream));
printf("Synchronize stream successfully\n");
CHECK_ERROR(aclrtMemcpy(dstHost.data(), bufferSize, dstDevice, bufferSize, ACL_MEMCPY_DEVICE_TO_HOST));
printf("\nVector addition result:\n");
bool resultMatched = true;
for (uint32_t i = 0; i < kElementCount; ++i) {
const float expected = srcAHost[i] + alpha * srcBHost[i];
printf(" result[%u] = %.1f (expected: %.1f)\n", i, dstHost[i], expected);
if (std::fabs(dstHost[i] - expected) > kTolerance) {
resultMatched = false;
}
}
CHECK_ERROR(aclrtFree(srcADevice));
CHECK_ERROR(aclrtFree(srcBDevice));
CHECK_ERROR(aclrtFree(dstDevice));
printf("Free device memory successfully\n");
CHECK_ERROR(aclrtDestroyStream(stream));
printf("Destroy stream successfully\n");
CHECK_ERROR(aclrtResetDeviceForce(deviceId));
printf("Reset device successfully\n");
CHECK_ERROR(aclFinalize());
printf("ACL finalize successfully\n");
if (!resultMatched) {
printf("\nSample run failed: vector addition result mismatched!\n");
return -1;
}
printf("\nSample run successfully with <<<>>> kernel call!\n");
return 0;
}