1 ! Copyright (C) 2010 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien alien.c-types alien.data alien.parser
4 alien.strings arrays assocs byte-arrays classes.struct
5 combinators continuations cuda.ffi destructors fry io
6 io.backend io.encodings.string io.encodings.utf8 kernel lexer
7 locals math math.parser namespaces opengl.gl.extensions
8 prettyprint quotations sequences ;
16 SYMBOL: cuda-memory-hashtable
18 ERROR: throw-cuda-error n ;
21 dup CUDA_SUCCESS = [ drop ] [ throw-cuda-error ] if ;
23 : cuda-version ( -- n )
24 int <c-object> [ cuDriverGetVersion cuda-error ] keep *int ;
30 { device integer initial: 0 }
31 { device-flags initial: 0 }
32 path block-shape shared-size grid ;
34 : with-cuda-context ( flags device quot -- )
36 [ CUcontext <c-object> ] 2dip
37 [ cuCtxCreate cuda-error ] 3keep 2drop *void*
40 [ drop '[ _ cuCtxDestroy cuda-error ] ] 2bi
43 : with-cuda-module ( path quot -- )
46 [ CUmodule <c-object> ] dip
47 [ cuModuleLoad cuda-error ] 2keep drop *void*
50 [ drop '[ _ cuModuleUnload cuda-error ] ] 2bi
53 : with-cuda-program ( flags device path quot -- )
54 [ dup cuda-device set ] 2dip
61 ] with-cuda-context ; inline
63 : with-cuda ( launcher quot -- )
66 H{ } clone cuda-memory-hashtable
70 [ [ device>> ] [ device-flags>> ] [ path>> ] tri ] bi
72 ] with-variable ; inline
76 : #cuda-devices ( -- n )
77 int <c-object> [ cuDeviceGetCount cuda-error ] keep *int ;
79 : n>cuda-device ( n -- device )
80 [ CUdevice <c-object> ] dip [ cuDeviceGet cuda-error ] 2keep drop *int ;
82 : enumerate-cuda-devices ( -- devices )
83 #cuda-devices iota [ n>cuda-device ] map ;
85 : cuda-device-properties ( device -- properties )
86 [ CUdevprop <c-object> ] dip
87 [ cuDeviceGetProperties cuda-error ] 2keep drop
88 CUdevprop memory>struct ;
92 : cuda-devices ( -- assoc )
93 enumerate-cuda-devices [ dup cuda-device-properties ] { } map>assoc ;
95 : cuda-device-name ( n -- string )
96 [ 256 [ <byte-array> ] keep ] dip
97 [ cuDeviceGetName cuda-error ]
98 [ 2drop utf8 alien>string ] 3bi ;
100 : cuda-device-capability ( n -- pair )
101 [ int <c-object> int <c-object> ] dip
102 [ cuDeviceComputeCapability cuda-error ]
103 [ drop [ *int ] bi@ ] 3bi 2array ;
105 : cuda-device-memory ( n -- bytes )
106 [ uint <c-object> ] dip
107 [ cuDeviceTotalMem cuda-error ]
110 : get-cuda-function* ( module string -- function )
111 [ CUfunction <c-object> ] 2dip
112 [ cuModuleGetFunction cuda-error ] 3keep 2drop *void* ;
114 : get-cuda-function ( string -- function )
115 [ cuda-module get ] dip get-cuda-function* ;
117 : with-cuda-function ( string quot -- )
119 get-cuda-function cuda-function set
122 : launch-function* ( function -- ) cuLaunch cuda-error ;
124 : launch-function ( -- ) cuda-function get cuLaunch cuda-error ;
126 : launch-function-grid* ( function width height -- )
127 cuLaunchGrid cuda-error ;
129 : launch-function-grid ( width height -- )
130 [ cuda-function get ] 2dip
131 cuLaunchGrid cuda-error ;
133 TUPLE: cuda-memory < disposable ptr length ;
135 : <cuda-memory> ( ptr length -- obj )
136 cuda-memory new-disposable
140 : add-cuda-memory ( obj -- obj )
141 dup dup ptr>> cuda-memory-hashtable get set-at ;
143 : delete-cuda-memory ( obj -- )
144 cuda-memory-hashtable delete-at ;
146 ERROR: invalid-cuda-memory ptr ;
148 : cuda-memory-length ( cuda-memory -- n )
149 ptr>> cuda-memory-hashtable get ?at [
155 M: cuda-memory byte-length length>> ;
157 : cuda-malloc ( n -- ptr )
158 [ CUdeviceptr <c-object> ] dip
159 [ cuMemAlloc cuda-error ] 2keep
160 [ *int ] dip <cuda-memory> add-cuda-memory ;
162 : cuda-free* ( ptr -- )
163 cuMemFree cuda-error ;
165 M: cuda-memory dispose ( ptr -- )
168 : host>device ( dest-ptr src-ptr -- )
169 [ ptr>> ] dip dup length cuMemcpyHtoD cuda-error ;
171 :: device>host ( ptr -- seq )
172 ptr byte-length <byte-array>
173 [ ptr [ ptr>> ] [ byte-length ] bi cuMemcpyDtoH cuda-error ] keep ;
175 : memcpy-device>device ( dest-ptr src-ptr count -- )
176 cuMemcpyDtoD cuda-error ;
178 : memcpy-device>array ( dest-array dest-index src-ptr count -- )
179 cuMemcpyDtoA cuda-error ;
181 : memcpy-array>device ( dest-ptr src-array src-index count -- )
182 cuMemcpyAtoD cuda-error ;
184 : memcpy-array>host ( dest-ptr src-array src-index count -- )
185 cuMemcpyAtoH cuda-error ;
187 : memcpy-host>array ( dest-array dest-index src-ptr count -- )
188 cuMemcpyHtoA cuda-error ;
190 : memcpy-array>array ( dest-array dest-index src-array src-ptr count -- )
191 cuMemcpyAtoA cuda-error ;
193 : cuda-int* ( function offset value -- )
194 cuParamSeti cuda-error ;
196 : cuda-int ( offset value -- )
197 [ cuda-function get ] 2dip cuda-int* ;
199 : cuda-float* ( function offset value -- )
200 cuParamSetf cuda-error ;
202 : cuda-float ( offset value -- )
203 [ cuda-function get ] 2dip cuda-float* ;
205 : cuda-vector* ( function offset ptr n -- )
206 cuParamSetv cuda-error ;
208 : cuda-vector ( offset ptr n -- )
209 [ cuda-function get ] 3dip cuda-vector* ;
211 : param-size* ( function n -- )
212 cuParamSetSize cuda-error ;
214 : param-size ( n -- )
215 [ cuda-function get ] dip param-size* ;
217 : malloc-device-string ( string -- n )
219 [ length cuda-malloc ] keep
220 [ host>device ] [ drop ] 2bi ;
222 ERROR: bad-cuda-parameter parameter ;
224 :: set-parameters ( seq -- )
225 cuda-function get :> function
230 { [ dup cuda-memory? ] [ ptr>> cuda-int ] }
231 { [ dup float? ] [ cuda-float ] }
232 { [ dup integer? ] [ cuda-int ] }
233 [ bad-cuda-parameter ]
239 : cuda-device-attribute ( attribute dev -- n )
240 [ int <c-object> ] 2dip
241 [ cuDeviceGetAttribute cuda-error ]
244 : function-block-shape* ( function x y z -- )
245 cuFuncSetBlockShape cuda-error ;
247 : function-block-shape ( x y z -- )
248 [ cuda-function get ] 3dip
249 cuFuncSetBlockShape cuda-error ;
251 : function-shared-size* ( function n -- )
252 cuFuncSetSharedSize cuda-error ;
254 : function-shared-size ( n -- )
255 [ cuda-function get ] dip
256 cuFuncSetSharedSize cuda-error ;
260 [ block-shape>> first3 function-block-shape ]
261 [ shared-size>> function-shared-size ]
266 first2 launch-function-grid
271 : cuda-device. ( n -- )
273 [ "Device: " write number>string print ]
274 [ "Name: " write cuda-device-name print ]
275 [ "Memory: " write cuda-device-memory number>string print ]
278 cuda-device-capability [ number>string ] map " " join print
280 [ "Properties: " write cuda-device-properties . ]
282 "CU_DEVICE_ATTRIBUTE_GPU_OVERLAP: " write
283 CU_DEVICE_ATTRIBUTE_GPU_OVERLAP swap
284 cuda-device-attribute number>string print
289 "CUDA Version: " write cuda-version number>string print nl
290 #cuda-devices iota [ nl ] [ cuda-device. ] interleave ;
295 { path "vocab:cuda/hello.ptx" }
296 { block-shape { 6 6 6 } }
301 "Hello World!" [ - ] map-index
302 malloc-device-string &dispose
304 [ 1array set-parameters ]
306 [ device>host utf8 alien>string . ] tri