2016-11-04 108 views
1
let prog = 
    """//Kernel code: 
extern "C" { 
    #pragma pack(1) 
    typedef struct { 
     int length; 
     float *pointer; 
    } global_array_float; 
    __global__ void kernel_main(global_array_float x){ 
     printf("(on device) x.length=%d\n",x.length); // prints: (on device) x.length=10 
     printf("(on device) x.pointer=%lld\n",x.pointer); // prints: (on device) x.pointer=0 
     printf("sizeof(global_array_float)=%d", sizeof(global_array_float)); // 12 bytes just as expected 
    } 
;}""" 

printfn "%s" prog 
let cuda_kernel = compile_kernel prog "kernel_main" 

let test_launcher(str: CudaStream, kernel: CudaKernel, x: CudaGlobalArray<float32>, o: CudaGlobalArray<float32>) = 
    let block_size = 1 

    kernel.GridDimensions <- dim3(1) 
    kernel.BlockDimensions <- dim3(block_size) 
    printfn "(on host) x.length=%i" x.length // prints: (on host) x.length=10 
    printfn "(on host) x.pointer=%i" x.pointer // prints: (on host) x.pointer=21535919104 
    let args: obj [] = [|x.length;x.pointer|] 
    kernel.RunAsync(str.Stream, args) 

let cols, rows = 10, 1 
let a = d2M.create((rows,cols)) 
     |> fun x -> fillRandomUniformMatrix ctx.Str x 1.0f 0.0f; x 
let a' = d2MtoCudaArray a 

//printfn "%A" (getd2M a) 

let o = d2M.create((rows,cols)) // o does nothing here as this is a minimalist example. 
let o' = d2MtoCudaArray o 

test_launcher(ctx.Str,cuda_kernel,a',o') 
cuda_context.Synchronize() 

//printfn "%A" (getd2M o) 

以下是我目前正在處理的main repo的摘錄。我非常接近Cuda C編譯器的F#語句,但我無法弄清楚如何從主機端正確傳遞參數。如何正確地將參數作爲結構傳遞給NVRTC?

儘管包裝雜注,NVRTC 7.5 Cuda編譯器正在做一些其他的優化,我不知道它是什麼。

因爲我正在關閉F#語句,所以我需要將參數作爲一個單獨的結構體傳遞給它。如果我將kernel_main(global_array_float x)的功能更改爲kernel_main(int x_length, float *x_pointer)之類的功能,那麼它可以工作,但我不是那種引用系統提供給我的形式,我希望避免做更多的工作來使F#更像C。

任何想法我可以嘗試嗎?

回答

1

我做了兩個錯誤的假設。

第一個錯誤是假設let args: obj [] = [|x.length;x.pointer|]將整齊放置在堆棧旁邊。實際上,這些是兩個不同的論點,第二個在上面傳遞時會在某處丟失。

它可以通過自定義結構類型並重寫如下表達式來修復:let args: obj [] = [|CudaLocalArray(x.length,x.pointer)|]

另外一個錯誤的假設,我發現當我像上面那樣重寫它時,使用[<StructLayout(LayoutKind.Sequential>]並不意味着這些字段將被打包在一起。相反,像C一樣,pack是一個參數,所以它需要像這樣使用:[<StructLayout(LayoutKind.Sequential,Pack=1)>]

相關問題