-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcusparse_benchmark.cu
More file actions
179 lines (150 loc) · 6.65 KB
/
Copy pathcusparse_benchmark.cu
File metadata and controls
179 lines (150 loc) · 6.65 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cuda_fp16.h> // For __half type
#include <cusparseLt.h>
#include <cuda_runtime.h>
// Define matrix dimensions and parameters
#define NUM_A_ROWS 128 // Number of rows in matrix A
#define NUM_A_COLS 128 // Number of columns in matrix A
#define NUM_B_ROWS 128 // Number of rows in matrix B
#define NUM_B_COLS 128 // Number of columns in matrix B
#define NUM_C_ROWS NUM_A_ROWS // Number of rows in matrix C
#define NUM_C_COLS NUM_B_COLS // Number of columns in matrix C
#define LDA NUM_A_COLS // Leading dimension of matrix A
#define LDB NUM_B_COLS // Leading dimension of matrix B
#define LDC NUM_C_COLS // Leading dimension of matrix C
#define ALIGNMENT 16 // Memory alignment
int main() {
// Scalars for multiplication
float alpha = 1.0f;
float beta = 0.0f;
// CUDA stream
cudaStream_t stream = nullptr;
// Create cuSPARSELt handle
cusparseLtHandle_t handle;
cusparseLtInit(&handle);
// Define matrix data types
cudaDataType type = CUDA_R_16F; // Half precision (__half)
cusparseOrder_t order = CUSPARSE_ORDER_ROW; // Row-major order
cusparseComputeType compute_type = CUSPARSE_COMPUTE_32F; // Compute in single precision
// Allocate memory for matrices on the device
__half *dA, *dB, *dC, *dD;
cudaMalloc(&dA, NUM_A_ROWS * NUM_A_COLS * sizeof(__half));
cudaMalloc(&dB, NUM_B_ROWS * NUM_B_COLS * sizeof(__half));
cudaMalloc(&dC, NUM_C_ROWS * NUM_C_COLS * sizeof(__half));
cudaMalloc(&dD, NUM_C_ROWS * NUM_C_COLS * sizeof(__half));
// Fill matrices with random data (for simplicity, using memset here)
cudaMemset(dA, 1, NUM_A_ROWS * NUM_A_COLS * sizeof(__half));
cudaMemset(dB, 1, NUM_B_ROWS * NUM_B_COLS * sizeof(__half));
cudaMemset(dC, 0, NUM_C_ROWS * NUM_C_COLS * sizeof(__half));
// Initialize matrix descriptors
cusparseLtMatDescriptor_t matA, matB, matC;
cusparseLtStructuredDescriptorInit(&handle, &matA, NUM_A_ROWS, NUM_A_COLS, LDA, ALIGNMENT, type, order, CUSPARSELT_SPARSITY_50_PERCENT);
cusparseLtDenseDescriptorInit(&handle, &matB, NUM_B_ROWS, NUM_B_COLS, LDB, ALIGNMENT, type, order);
cusparseLtDenseDescriptorInit(&handle, &matC, NUM_C_ROWS, NUM_C_COLS, LDC, ALIGNMENT, type, order);
// Initialize matmul descriptor and plan
cusparseLtMatmulDescriptor_t matmul;
cusparseLtMatmulAlgSelection_t alg_sel;
cusparseLtMatmulPlan_t plan;
cusparseLtMatmulDescriptorInit(&handle, &matmul, CUSPARSE_OPERATION_NON_TRANSPOSE, CUSPARSE_OPERATION_NON_TRANSPOSE, &matA, &matB, &matC, &matC, compute_type);
cusparseLtMatmulAlgSelectionInit(&handle, &alg_sel, &matmul, CUSPARSELT_MATMUL_ALG_DEFAULT);
cusparseLtMatmulPlanInit(&handle, &plan, &matmul, &alg_sel);
float elapsed_time_ms = 0.0f;
// Prune matrix A
// Prune matrix A (in-place)
cusparseStatus_t status = cusparseLtSpMMAPrune(
&handle, // Pointer to cuSPARSELt handle
&matmul, // Pointer to matmul descriptor
dA, // Input matrix (device pointer)
dA, // Output matrix (in-place pruning)
CUSPARSELT_PRUNE_SPMMA_TILE, // Pruning algorithm
stream); // CUDA stream
// Check for errors
if (status != CUSPARSE_STATUS_SUCCESS) {
std::cerr << "Matrix pruning failed!" << std::endl;
return EXIT_FAILURE;
}
// Check pruning correctness
int *d_valid;
cudaMalloc((void **)&d_valid, sizeof(int));
cusparseLtSpMMAPruneCheck(&handle, &matmul, dA, d_valid, stream);
int is_valid;
cudaMemcpyAsync(&is_valid, d_valid, sizeof(int), cudaMemcpyDeviceToHost, stream);
cudaStreamSynchronize(stream);
if (is_valid != 0) {
std::cerr << "Pruned matrix A is invalid!" << std::endl;
return EXIT_FAILURE;
}
// Compress matrix A
// size_t compressed_size;
// cusparseLtSpMMACompressedSize(&handle, &plan, &compressed_size);
size_t compressed_size;
size_t compress_buffer_size;
// Create CUDA events
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
// Record the start event
cudaEventRecord(start, stream);
cusparseLtSpMMACompressedSize(
&handle, // Pointer to cuSPARSELt handle
&plan, // Pointer to matmul plan
&compressed_size, // Pointer to store compressed size
&compress_buffer_size // Pointer to store buffer size
);
void *dA_compressed;
void* compress_buffer;
cudaMalloc(&dA_compressed, compressed_size);
cudaMalloc(&compress_buffer, compress_buffer_size);
// cusparseLtSpMMACompress(&handle, &plan, dA, dA_compressed, stream);
cusparseStatus_t compress_status = cusparseLtSpMMACompress(
&handle, // Pointer to cuSPARSELt handle
&plan, // Pointer to matmul plan
dA, // Dense input matrix (device pointer)
dA_compressed, // Output compressed matrix (device pointer)
compress_buffer, // Temporary buffer for compression (device pointer)
stream // CUDA stream
);
// Allocate workspace
size_t workspace_size;
cusparseLtMatmulGetWorkspace(&handle, &plan, &workspace_size);
void *d_workspace = nullptr;
if (workspace_size > 0) {
cudaMalloc(&d_workspace, workspace_size);
}
// Record the start event
cudaEventRecord(start, stream);
// Perform matrix multiplication
cusparseStatus_t matmul_status = cusparseLtMatmul(&handle, &plan, &alpha, dA_compressed, dB, &beta, dC, dD, d_workspace, &stream, 0);
// Record the stop event
cudaEventRecord(stop, stream);
cudaEventSynchronize(stop);
// Calculate the elapsed time
cudaEventElapsedTime(&elapsed_time_ms, start, stop);
// Print the elapsed time
if (matmul_status == CUSPARSE_STATUS_SUCCESS) {
std::cout << "Matrix multiplication completed in " << elapsed_time_ms << " ms" << std::endl;
} else {
std::cerr << "Matrix multiplication failed!" << std::endl;
return EXIT_FAILURE;
}
// Destroy CUDA events
cudaEventDestroy(start);
cudaEventDestroy(stop);
// Cleanup
cusparseLtMatDescriptorDestroy(&matA);
cusparseLtMatDescriptorDestroy(&matB);
cusparseLtMatDescriptorDestroy(&matC);
cusparseLtMatmulPlanDestroy(&plan);
cusparseLtDestroy(&handle);
cudaFree(dA);
cudaFree(dB);
cudaFree(dC);
cudaFree(dD);
cudaFree(dA_compressed);
cudaFree(d_workspace);
cudaFree(d_valid);
std::cout << "Matrix multiplication completed successfully!" << std::endl;
return EXIT_SUCCESS;
}