运行时环境层

编写代码使用 MUSA Runtime API 执行向量加法,使用 MUSA 平台在 GPU 上执行并行计算。包含内存管理、数据传输、核函数调用和资源清理的典型 GPU 编程流程。与 CUDA 类似的 API 结构,但适配摩尔线程 GPU。。主要步骤:

  • 定义核函数 VectorAdd

  • 内存分配与初始化: 使用 musaMalloc 在设备上分配内存,通过 malloc 在主机端分配内存。

  • 数据传输: 使用 musaMemcpy 在主机与设备之间传输数据。

  • 核函数启动: 启动 VectorAdd 核函数,传入设备端的数组 dAdB

  • 错误检查: 使用 musaGetLastError 检查内核执行时的错误。

  • 资源释放: 释放分配的内存和流资源。

    示例代码:

#include "musa_runtime.h"

__global__ void VectorAdd(int* a, int* b) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    a[idx] = a[idx] + b[idx];
}

int main() {
    const size_t numElements = 4096;
    const size_t sizeBytes = numElements * sizeof(int);

    musaStream_t stream;
    musaStreamCreate(&stream);

    int *hA = nullptr, *hB = nullptr;
    int *dA = nullptr, *dB = nullptr;
    hA = reinterpret_cast<int*>(malloc(sizeBytes));
    hB = reinterpret_cast<int*>(malloc(sizeBytes));
    musaMalloc(&dA, sizeBytes);
    musaMalloc(&dB, sizeBytes);

    for (int i = 0; i < numElements; ++i) {
        hA[i] = i;
        hB[i] = 2 * i;
    }

    musaMemcpy(dA, hA, sizeBytes, musaMemcpyHostToDevice);
    musaMemcpy(dB, hB, sizeBytes, musaMemcpyHostToDevice);

    int threadsPerBlock = 1024;
    int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock;

    VectorAdd<<<blocksPerGrid, threadsPerBlock>>>(dA, dB);
    musaError_t err = musaGetLastError();

    musaMemcpy(hA, dA, sizeBytes, musaMemcpyDeviceToHost);

    musaStreamDestroy(stream);
    free(hA);
    free(hB);
    musaFree(dA);
    musaFree(dB);

    return 0;
}