@@ -19,6 +19,9 @@ pub use crate::offload;
1919/// Defaults to `[1, 1, 1]`.
2020/// - `dyn_cache`: The amount of dynamic shared memory, in bytes, to allocate for the kernel.
2121/// Defaults to `0`.
22+ /// - `device`: The index of the device to offload to. Must be `>= 0`. If omitted, the
23+ /// default device is used. Use [`crate::intrinsics::offload_get_num_devices`] to discover
24+ /// which device ids are valid.
2225///
2326/// Each argument may only be specified once.
2427///
@@ -43,61 +46,82 @@ macro_rules! offload {
4346 workgroup_dim = ( [ 1 , 1 , 1 ] ) ;
4447 thread_dim = ( [ 1 , 1 , 1 ] ) ;
4548 dyn_cache = ( 0 ) ;
49+ device = NONE ;
4650 args = NONE
4751 )
4852 } ;
4953
50- ( @munch [ kernel = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = NONE ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
51- $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = ( SOME $val) ; workgroup_dim = $w; thread_dim = $t; dyn_cache = $d; args = $a)
54+ ( @munch [ kernel = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = NONE ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
55+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = ( SOME $val) ; workgroup_dim = $w; thread_dim = $t; dyn_cache = $d; device = $device ; args = $a)
5256 } ;
53- ( @munch [ kernel = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = ( SOME $old: expr) ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
57+ ( @munch [ kernel = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = ( SOME $old: expr) ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
5458 compile_error!( "duplicate field `kernel`" )
5559 } ;
56- ( @munch [ workgroup_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = ( [ 1 , 1 , 1 ] ) ; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
57- $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = ( SOME $val) ; thread_dim = $t; dyn_cache = $d; args = $a)
60+ ( @munch [ workgroup_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = ( [ 1 , 1 , 1 ] ) ; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
61+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = ( SOME $val) ; thread_dim = $t; dyn_cache = $d; device = $device ; args = $a)
5862 } ;
59- ( @munch [ workgroup_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = ( SOME $old: expr) ; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
63+ ( @munch [ workgroup_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = ( SOME $old: expr) ; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
6064 compile_error!( "duplicate field `workgroup_dim`" )
6165 } ;
62- ( @munch [ thread_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = ( [ 1 , 1 , 1 ] ) ; dyn_cache = $d: tt; args = $a: tt) => {
63- $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = ( SOME $val) ; dyn_cache = $d; args = $a)
66+ ( @munch [ thread_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = ( [ 1 , 1 , 1 ] ) ; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
67+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = ( SOME $val) ; dyn_cache = $d; device = $device ; args = $a)
6468 } ;
65- ( @munch [ thread_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = ( SOME $old: expr) ; dyn_cache = $d: tt; args = $a: tt) => {
69+ ( @munch [ thread_dim = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = ( SOME $old: expr) ; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
6670 compile_error!( "duplicate field `thread_dim`" )
6771 } ;
68- ( @munch [ dyn_cache = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = ( 0 ) ; args = $a: tt) => {
69- $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = $t; dyn_cache = ( SOME $val) ; args = $a)
72+ ( @munch [ dyn_cache = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = ( 0 ) ; device = $device : tt ; args = $a: tt) => {
73+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = $t; dyn_cache = ( SOME $val) ; device = $device ; args = $a)
7074 } ;
71- ( @munch [ dyn_cache = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = ( SOME $old: expr) ; args = $a: tt) => {
75+ ( @munch [ dyn_cache = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = ( SOME $old: expr) ; device = $device : tt ; args = $a: tt) => {
7276 compile_error!( "duplicate field `dyn_cache`" )
7377 } ;
74- ( @munch [ args = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = NONE ) => {
75- $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = $t; dyn_cache = $d; args = ( SOME $val) )
78+ ( @munch [ device = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = NONE ; args = $a : tt ) => {
79+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = $t; dyn_cache = $d; device = ( SOME $val) ; args = $a )
7680 } ;
77- ( @munch [ args = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = ( SOME $old: expr) ) => {
81+ ( @munch [ device = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = ( SOME $old: expr) ; args = $a: tt) => {
82+ compile_error!( "duplicate field `device`" )
83+ } ;
84+ ( @munch [ args = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device: tt; args = NONE ) => {
85+ $crate:: offload!( @munch [ $( $rest_f = $rest_v) ,* ] ; kernel = $k; workgroup_dim = $w; thread_dim = $t; dyn_cache = $d; device = $device; args = ( SOME $val) )
86+ } ;
87+ ( @munch [ args = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device: tt; args = ( SOME $old: expr) ) => {
7888 compile_error!( "duplicate field `args`" )
7989 } ;
8090
81- ( @munch [ $invalid: ident = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
91+ ( @munch [ $invalid: ident = $val: expr $( , $rest_f: ident = $rest_v: expr) * ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
8292 compile_error!( concat!( "unknown field `" , stringify!( $invalid) , "`" ) )
8393 } ;
8494
85- ( @munch [ ] ; kernel = NONE ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = $a: tt) => {
95+ ( @munch [ ] ; kernel = NONE ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = $a: tt) => {
8696 compile_error!( "missing `kernel`" )
8797 } ;
88- ( @munch [ ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = NONE ) => {
98+ ( @munch [ ] ; kernel = $k: tt; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = NONE ) => {
8999 compile_error!( "missing `args`" )
90100 } ;
91- ( @munch [ ] ; kernel = ( SOME $kernel: expr) ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; args = ( SOME $args: expr) ) => {
101+ ( @munch [ ] ; kernel = ( SOME $kernel: expr) ; workgroup_dim = $w: tt; thread_dim = $t: tt; dyn_cache = $d: tt; device = $device : tt ; args = ( SOME $args: expr) ) => {
92102 $crate:: intrinsics:: offload:: <_, _, ( ) >(
93103 $kernel,
94104 $crate:: offload!( @value $w) ,
95105 $crate:: offload!( @value $t) ,
96106 $crate:: offload!( @value $d) ,
107+ $crate:: offload!( @device $device) ,
97108 $args,
98109 )
99110 } ;
100111
101112 ( @value ( SOME $val: expr) ) => { $val } ;
102113 ( @value ( $val: expr) ) => { $val } ;
114+
115+ // if `device` is omitted (`NONE), we use the OpenMP default device (`-1`)
116+ ( @device NONE ) => { -1 } ;
117+ ( @device ( SOME $val: expr) ) => { {
118+ const { $crate:: assert!( $val >= 0 , "offload device must be non-negative; omit `device` to use the default device" ) } ;
119+ let device: i32 = $val;
120+ $crate:: assert!(
121+ device < $crate:: intrinsics:: offload_get_num_devices( ) ,
122+ "offload device {} is not available" ,
123+ device,
124+ ) ;
125+ device
126+ } } ;
103127}
0 commit comments