#include <cstdio>
#include <cstdlib>
#include <vector>
#include <musa_runtime.h>
#include <mublasLt.h>
#include <musa_fp16.h>
#include <musa.h>
#define MUBLAS_CHECK(cmd) \
do { \
mublasStatus_t status = (cmd); \
if (status != MUBLAS_STATUS_SUCCESS) { \
fprintf(stderr, "muBLASLt error %d at %s:%d\n", \
status, __FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
} while (0)
#define MUSA_CHECK(cmd) \
do { \
musaError_t err = (cmd); \
if (err != musaSuccess) { \
fprintf(stderr, "MUSA error: %s at %s:%d\n", \
musaGetErrorString(err), __FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
} while (0)
int main() {
const int M = 256, N = 256, K = 256;
const __half alpha = __float2half(1.0f);
const __half beta = __float2half(0.0f);
mublasLtHandle_t handle;
MUBLAS_CHECK(mublasLtCreate(&handle));
mublasLtMatrixLayout_t Adesc, Bdesc, Cdesc, Ddesc;
MUBLAS_CHECK(mublasLtMatrixLayoutCreate(&Adesc, MUSA_R_16F, M, K, K));
MUBLAS_CHECK(mublasLtMatrixLayoutCreate(&Bdesc, MUSA_R_16F, K, N, N));
MUBLAS_CHECK(mublasLtMatrixLayoutCreate(&Cdesc, MUSA_R_16F, M, N, N));
MUBLAS_CHECK(mublasLtMatrixLayoutCreate(&Ddesc, MUSA_R_16F, M, N, N));
mublasLtMatmulDesc_t computeDesc;
MUBLAS_CHECK(mublasLtMatmulDescCreate(&computeDesc,
MUBLAS_COMPUTE_16F, MUSA_R_16F));
mublasOperation_t transa = MUBLAS_OP_N;
mublasOperation_t transb = MUBLAS_OP_N;
MUBLAS_CHECK(mublasLtMatmulDescSetAttribute(
computeDesc, MUBLASLT_MATMUL_DESC_TRANSA,
&transa, sizeof(transa)));
MUBLAS_CHECK(mublasLtMatmulDescSetAttribute(
computeDesc, MUBLASLT_MATMUL_DESC_TRANSB,
&transb, sizeof(transb)));
mublasLtEpilogue_t epilogue = MUBLASLT_EPILOGUE_RELU_BIAS;
MUBLAS_CHECK(mublasLtMatmulDescSetAttribute(
computeDesc, MUBLASLT_MATMUL_DESC_EPILOGUE,
&epilogue, sizeof(epilogue)));
mublasLtMatmulPreference_t preference;
MUBLAS_CHECK(mublasLtMatmulPreferenceCreate(&preference));
size_t workspaceSize = 32 * 1024 * 1024;
MUBLAS_CHECK(mublasLtMatmulPreferenceSetAttribute(
preference,
MUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES,
&workspaceSize,
sizeof(workspaceSize)));
mublasLtMatmulHeuristicResult_t heuristicResult;
int returnedResults = 0;
MUBLAS_CHECK(mublasLtMatmulAlgoGetHeuristic(
handle, computeDesc,
Adesc, Bdesc, Cdesc, Ddesc,
preference, 1,
&heuristicResult,
&returnedResults));
if (returnedResults == 0) {
fprintf(stderr, "No algorithm found\n");
return -1;
}
__half *d_A, *d_B, *d_C, *d_D, *d_bias;
void* workspace;
MUSA_CHECK(musaMalloc(&d_A, M * K * sizeof(__half)));
MUSA_CHECK(musaMalloc(&d_B, K * N * sizeof(__half)));
MUSA_CHECK(musaMalloc(&d_C, M * N * sizeof(__half)));
MUSA_CHECK(musaMalloc(&d_D, M * N * sizeof(__half)));
MUSA_CHECK(musaMalloc(&d_bias, N * sizeof(__half)));
MUSA_CHECK(musaMalloc(&workspace, workspaceSize));
std::vector<__half> h_A(M * K);
std::vector<__half> h_B(K * N);
std::vector<__half> h_C(M * N);
std::vector<__half> h_bias(N);
for (int i = 0; i < M * K; i++) h_A[i] = __float2half(1.0f);
for (int i = 0; i < K * N; i++) h_B[i] = __float2half(1.0f);
for (int i = 0; i < M * N; i++) h_C[i] = __float2half(0.0f);
for (int i = 0; i < N; i++) h_bias[i] = __float2half(0.5f);
MUSA_CHECK(musaMemcpy(d_A, h_A.data(), M*K*sizeof(__half), musaMemcpyHostToDevice));
MUSA_CHECK(musaMemcpy(d_B, h_B.data(), K*N*sizeof(__half), musaMemcpyHostToDevice));
MUSA_CHECK(musaMemcpy(d_C, h_C.data(), M*N*sizeof(__half), musaMemcpyHostToDevice));
MUSA_CHECK(musaMemcpy(d_bias, h_bias.data(), N*sizeof(__half), musaMemcpyHostToDevice));
MUBLAS_CHECK(mublasLtMatmulDescSetAttribute(
computeDesc,
MUBLASLT_MATMUL_DESC_BIAS_POINTER,
&d_bias,
sizeof(d_bias)));
MUBLAS_CHECK(mublasLtMatmul(
handle,
computeDesc,
&alpha,
d_A, Adesc,
d_B, Bdesc,
&beta,
d_C, Cdesc,
d_D, Ddesc,
&heuristicResult.algo,
workspace,
workspaceSize,
0));
MUSA_CHECK(musaStreamSynchronize(0));
std::vector<__half> h_D(M * N);
MUSA_CHECK(musaMemcpy(h_D.data(), d_D, M*N*sizeof(__half), musaMemcpyDeviceToHost));
float result = __half2float(h_D[0]);
printf("D[0] = %f (expected ~ %f)\n", result, K + 0.5f);
MUSA_CHECK(musaFree(d_A));
MUSA_CHECK(musaFree(d_B));
MUSA_CHECK(musaFree(d_C));
MUSA_CHECK(musaFree(d_D));
MUSA_CHECK(musaFree(d_bias));
MUSA_CHECK(musaFree(workspace));
MUBLAS_CHECK(mublasLtMatmulPreferenceDestroy(preference));
MUBLAS_CHECK(mublasLtMatmulDescDestroy(computeDesc));
MUBLAS_CHECK(mublasLtMatrixLayoutDestroy(Adesc));
MUBLAS_CHECK(mublasLtMatrixLayoutDestroy(Bdesc));
MUBLAS_CHECK(mublasLtMatrixLayoutDestroy(Cdesc));
MUBLAS_CHECK(mublasLtMatrixLayoutDestroy(Ddesc));
MUBLAS_CHECK(mublasLtDestroy(handle));
return 0;
}