[英]How does cudaLaunchKernel know the array size of “void **args”?
我知道數組的大小可以通過以下代碼獲得:
int a = 12;
float b = 12.0f;
char c = 'c';
void *param[] = { (void*)&a, (void*)&b, (void*)&c };
// the element size of param
size_t size = sizeof(param)/sizeof(void*);
但現在,我希望將param
傳遞給名為TryToGetTheSize
的函數,並獲取一個大小作為返回值。
size_t TryToGetTheSize(void **array)
{
// return the size of void* array
}
...
size_t size = TryToGetTheSize(param);
我已經從strlen
的實現中嘗試了一個想法,它將char*
指針遞增地移動到下一個連續的內存空間,並通過檢查計數當前位置的值是否為'\\0'
。
但是該方法不適用於void**
,沒有辦法檢查void*
指示地址的驗證。
因此,僅使用void** array
似乎無法知道大小,但是當我查找CUDA API時,我發現:
cudaLaunchKernel(const void* func, dim3 gridDim, dim3 blockDim, void** args, size_t sharedMem, cudaStream_t stream)
在CUDA中,我們通常使用<<<>>>
作為內核啟動,但是如果我們手動設置arugments並直接調用cudaLaunchKernel
則相同
在cudaLaunchKerenl
API中,我注意到第四個參數args
用作內核函數func
參數,並且沒有其他參數描述args
的大小
所以,我有兩個問題:
1) cudaLaunchKernel
如何知道void** args
的大小?
2)如果cudaLaunchKernel
不需要知道void** args
的大小,它是如何工作的?
以下是我在內核啟動時使用cudaLaunchKernel
而不是<<<>>>
示例代碼。
#include<stdio.h>
#include<stdlib.h>
#include<cuda_runtime.h>
__global__
void saxpy(int n, float a, float *x, float *y)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n) y[i] = a * x[i] + y[i];
}
int main(void)
{
int N = 1 << 20;
float *hx, *hy, *dx, *dy;
hx = (float*)malloc(N * sizeof(float));
hy = (float*)malloc(N * sizeof(float));
cudaMalloc(&dx, N * sizeof(float));
cudaMalloc(&dy, N * sizeof(float));
for (int idx = 0; idx < N; idx++)
{
hx[idx] = 1.0f;
hy[idx] = 2.0f;
}
cudaMemcpy(dx, hx, N * sizeof(float), cudaMemcpyHostToDevice);
cudaMemcpy(dy, hy, N * sizeof(float), cudaMemcpyHostToDevice);
unsigned int threads = 256;
unsigned int blocks = (N + 255) / threads;
float ratio = 2.0f;
//saxpy<<<blocks, threads>>>(N, ratio, dx, dy);
void *args[] = { &N, &ratio, &dx, &dy };
cudaLaunchKernel((void*)saxpy, dim3(blocks), dim3(threads), args, 0, NULL);
cudaMemcpy(hy, dy, N * sizeof(float), cudaMemcpyDeviceToHost);
float max_error = 0.0f;
for (int jdx = 0; jdx < N; jdx++)
{
max_error = max(max_error, abs(hy[jdx] - 4.0f));
}
printf("Max Error: %f\n", max_error);
cudaFree(dx);
cudaFree(dy);
free(hx);
free(hy);
return 0;
}
引自相關文檔 :
不需要指定內核參數的數量及其偏移量和大小,因為直接從內核的映像中檢索該信息。
每個CUDA設備函數都將其參數列表與靜態編譯的函數代碼一起存儲。 因此,API確切地知道調用cudaLaunchKernel
需要多少個參數條目。 如果您為啟動呼叫提供的數量太少,您將獲得段錯誤或未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.