@@ -1288,14 +1288,14 @@ def format_reverse_call_args(
12881288 args ,
12891289 args_out ,
12901290 use_initializer_list ,
1291- hidden_args = None ,
1291+ extra_args = None ,
12921292 has_output_args = True ,
12931293 require_original_output_arg = False ,
12941294 ):
1295- if hidden_args is None :
1296- hidden_args = []
1295+ if extra_args is None :
1296+ extra_args = []
12971297 formatted_var = adj .format_args ("var" , args_var )
1298- formatted_hidden = adj .format_args ("var" , hidden_args )
1298+ formatted_extra = adj .format_args ("var" , extra_args )
12991299 formatted_out = []
13001300 if has_output_args and (require_original_output_arg or len (args_out ) > 1 ):
13011301 formatted_out = adj .format_args ("var" , args_out )
@@ -1311,18 +1311,16 @@ def format_reverse_call_args(
13111311
13121312 if use_initializer_list :
13131313 var_str = f"{{{ ', ' .join (formatted_var )} }}"
1314- hidden_str = ", " .join (formatted_hidden )
1314+ extra_str = ", " .join (formatted_extra )
13151315 out_str = f"{{{ ', ' .join (formatted_out )} }}"
13161316 adj_str = f"{{{ ', ' .join (formatted_var_adj )} }}"
13171317 out_adj_str = ", " .join (formatted_out_adj )
13181318 if len (args_out ) > 1 :
1319- arg_str = ", " .join (x for x in [var_str , hidden_str , out_str , adj_str , out_adj_str ] if x )
1319+ arg_str = ", " .join (x for x in [var_str , extra_str , out_str , adj_str , out_adj_str ] if x )
13201320 else :
1321- arg_str = ", " .join (x for x in [var_str , hidden_str , adj_str , out_adj_str ] if x )
1321+ arg_str = ", " .join (x for x in [var_str , extra_str , adj_str , out_adj_str ] if x )
13221322 else :
1323- arg_str = ", " .join (
1324- formatted_var + formatted_hidden + formatted_out + formatted_var_adj + formatted_out_adj
1325- )
1323+ arg_str = ", " .join (formatted_var + formatted_extra + formatted_out + formatted_var_adj + formatted_out_adj )
13261324 return arg_str
13271325
13281326 def indent (adj ):
@@ -1708,27 +1706,27 @@ def add_call(adj, func, args, kwargs, type_args, min_outputs=None):
17081706
17091707 fwd_args .append (strip_reference (func_arg_var ))
17101708
1711- det_hidden_args = []
1709+ det_args = []
17121710 if not func .is_builtin ():
1713- det_hidden_args = _deterministic_call_hidden_args (func .adj .det_meta , bound_args )
1711+ det_args = _deterministic_call_args (func .adj .det_meta , bound_args )
17141712
17151713 if return_type is None :
17161714 # handles expression (zero output) functions, e.g.: void do_something();
1717- forward_call = f"{ func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_hidden_args , use_initializer_list )} );"
1715+ forward_call = f"{ func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_args , use_initializer_list )} );"
17181716 replay_call = forward_call
17191717 if func .custom_replay_func is not None or func .replay_snippet is not None :
1720- replay_call = f"{ func .namespace } replay_{ func_name } ({ adj .format_forward_call_args (fwd_args + det_hidden_args , use_initializer_list )} );"
1718+ replay_call = f"{ func .namespace } replay_{ func_name } ({ adj .format_forward_call_args (fwd_args + det_args , use_initializer_list )} );"
17211719
17221720 elif not isinstance (return_type , Sequence ) or len (return_type ) == 1 :
17231721 # handle simple function (one output)
1724- forward_call = f"var_{ output } = { func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_hidden_args , use_initializer_list )} );"
1722+ forward_call = f"var_{ output } = { func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_args , use_initializer_list )} );"
17251723 replay_call = forward_call
17261724 if func .custom_replay_func is not None :
1727- replay_call = f"var_{ output } = { func .namespace } replay_{ func_name } ({ adj .format_forward_call_args (fwd_args + det_hidden_args , use_initializer_list )} );"
1725+ replay_call = f"var_{ output } = { func .namespace } replay_{ func_name } ({ adj .format_forward_call_args (fwd_args + det_args , use_initializer_list )} );"
17281726
17291727 else :
17301728 # handle multiple value functions
1731- forward_call = f"{ func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_hidden_args + output , use_initializer_list )} );"
1729+ forward_call = f"{ func .namespace } { func_name } ({ adj .format_forward_call_args (fwd_args + det_args + output , use_initializer_list )} );"
17321730 replay_call = forward_call
17331731
17341732 if func .skip_replay :
@@ -1750,7 +1748,7 @@ def add_call(adj, func, args, kwargs, type_args, min_outputs=None):
17501748 adj_args ,
17511749 output_list ,
17521750 use_initializer_list ,
1753- hidden_args = det_hidden_args ,
1751+ extra_args = det_args ,
17541752 has_output_args = reverse_has_output_args ,
17551753 require_original_output_arg = func .require_original_output_arg ,
17561754 )
@@ -1812,18 +1810,7 @@ def _emit_deterministic_atomic(adj, func, bound_args, return_type, output, outpu
18121810 value_ctype = Var .dtype_to_ctype (value_dtype )
18131811 scalar_ctype = warp_type_to_ctype (scalar_dtype )
18141812
1815- # C++ zero literal for the value type.
1816- # Cannot use "float(0)" because Warp defines a macro #define float(x) cast_float(x).
1817- _ZERO_LITERALS = {
1818- "float" : "0.0f" ,
1819- "double" : "0.0" ,
1820- "wp::half" : "wp::half(0)" ,
1821- "int" : "0" ,
1822- "unsigned int" : "0u" ,
1823- "int64_t" : "int64_t(0)" ,
1824- "uint64_t" : "uint64_t(0)" ,
1825- }
1826- zero_literal = _ZERO_LITERALS .get (scalar_ctype , f"{ scalar_ctype } (0)" )
1813+ zero_expr = _cinit_expr (return_type )
18271814
18281815 # Map from builtin name to reduction op
18291816 op_map = {
@@ -1863,20 +1850,10 @@ def _emit_deterministic_atomic(adj, func, bound_args, return_type, output, outpu
18631850
18641851 val_loaded = loaded_args [- 1 ] # already loaded above
18651852
1866- adj .add_forward ("#ifdef __CUDA_ARCH__" , skip_replay = True )
18671853 adj .add_forward (
1868- f"if (det_ctx.phase == 0) {{ "
1869- f"{ helper_name } .contrib[det_ctx.idx] += var_{ val_loaded } ; "
1870- f"var_{ output } = { zero_literal } ; "
1871- f"}} else {{ "
1872- f"var_{ output } = static_cast<{ scalar_ctype } >({ helper_name } .prefix[det_ctx.idx]); "
1873- f"{ helper_name } .prefix[det_ctx.idx] += var_{ val_loaded } ; "
1874- f"}}" ,
1854+ f"WP_DET_COUNTER_OR_FALLBACK(var_{ output } , det_ctx, { helper_name } , var_{ val_loaded } , { cpu_call } );" ,
18751855 replay = "// deterministic counter replay (skipped)" ,
18761856 )
1877- adj .add_forward ("#else" , skip_replay = True )
1878- adj .add_forward (cpu_call , replay = "// " + cpu_call )
1879- adj .add_forward ("#endif" , skip_replay = True )
18801857 return output
18811858
18821859 # Pattern A: Accumulation (return value unused)
@@ -1921,20 +1898,12 @@ def _emit_deterministic_atomic(adj, func, bound_args, return_type, output, outpu
19211898 if func .key == "atomic_sub" :
19221899 val_expr = f"(-{ val_expr } )"
19231900
1924- adj .add_forward ("#ifdef __CUDA_ARCH__" , skip_replay = True )
19251901 adj .add_forward (
1926- "if (det_ctx.phase != 0) { "
1927- f"wp::deterministic::scatter("
1928- f"det_ctx, { helper_name } , "
1929- f"static_cast<int>({ flat_idx_expr } ), { val_expr } );"
1930- " }" ,
1902+ f"WP_DET_SCATTER_OR_FALLBACK(det_ctx, { helper_name } , { flat_idx_expr } , { val_expr } , { cpu_call } );" ,
19311903 replay = "// deterministic scatter replay (skipped)" ,
19321904 )
19331905 if output is not None :
1934- adj .add_forward (f"var_{ output } = { zero_literal } ;" )
1935- adj .add_forward ("#else" , skip_replay = True )
1936- adj .add_forward (cpu_call , replay = "// " + cpu_call )
1937- adj .add_forward ("#endif" , skip_replay = True )
1906+ adj .add_forward (f"var_{ output } = { zero_expr } ;" )
19381907 return output
19391908
19401909 def add_grad_call (adj , func , args , kwargs ):
@@ -3470,14 +3439,8 @@ def _store_subscript(adj, lhs, target, indices, rhs):
34703439 # phase 0 so the counting pass does not introduce side effects.
34713440 if adj .det_meta is not None and adj .det_meta .has_counter :
34723441 loaded_store_args = [adj .load (x ) for x in (target , * indices , rhs )]
3473- cpu_store_args = ", " .join (f"var_{ x } " for x in loaded_store_args )
3474- adj .add_forward ("#ifdef __CUDA_ARCH__" , skip_replay = True )
3475- adj .add_forward ("if (_wp_det_phase != 0) {" , skip_replay = True )
3476- adj .add_builtin_call ("array_store" , [target , * indices , rhs ])
3477- adj .add_forward ("}" , skip_replay = True )
3478- adj .add_forward ("#else" , skip_replay = True )
3479- adj .add_forward (f"wp::array_store({ cpu_store_args } );" )
3480- adj .add_forward ("#endif" , skip_replay = True )
3442+ store_args = ", " .join (f"var_{ x } " for x in loaded_store_args )
3443+ adj .add_forward (f"WP_DET_STORE_IF_ACTIVE(det_ctx, { store_args } );" , skip_replay = True )
34813444 else :
34823445 adj .add_builtin_call ("array_store" , [target , * indices , rhs ])
34833446
@@ -4947,9 +4910,9 @@ def codegen_func(adj, c_func_name: str, device="cpu", options=None, forward_only
49474910 forward_args .append (s )
49484911 if not adj .custom_reverse_mode or i < adj .custom_reverse_num_input_args :
49494912 reverse_args .append (s )
4950- hidden_args = _deterministic_function_hidden_args (adj )
4951- forward_args .extend (hidden_args )
4952- reverse_args .extend (hidden_args )
4913+ det_args = _deterministic_function_args (adj )
4914+ forward_args .extend (det_args )
4915+ reverse_args .extend (det_args )
49534916 if has_multiple_outputs :
49544917 for i , arg in enumerate (adj .return_var ):
49554918 forward_args .append (arg .ctype () + " & ret_" + str (i ))
@@ -5117,42 +5080,38 @@ def codegen_snippet(adj, name, snippet, adj_snippet, replay_snippet, forward_onl
51175080 return s
51185081
51195082
5120- def _deterministic_function_hidden_args (adj ):
5083+ def _deterministic_function_args (adj ):
51215084 if adj .det_meta is None or not adj .det_meta .needs_deterministic :
51225085 return []
51235086
51245087 from warp ._src .deterministic import counter_cpp_type , scatter_cpp_type # noqa: PLC0415
51255088
5126- hidden_args = ["wp::det_ctx det_ctx" ]
5089+ det_args = ["wp::det_ctx det_ctx" ]
51275090 for target in adj .det_meta .counter_targets :
5128- hidden_args .append (f"{ counter_cpp_type (target )} { target .helper_name } " )
5091+ det_args .append (f"{ counter_cpp_type (target )} { target .helper_name } " )
51295092 for target in adj .det_meta .scatter_targets :
5130- hidden_args .append (f"{ scatter_cpp_type (target )} { target .helper_name } " )
5131- return hidden_args
5093+ det_args .append (f"{ scatter_cpp_type (target )} { target .helper_name } " )
5094+ return det_args
51325095
51335096
5134- def _deterministic_kernel_hidden_args (adj ):
5097+ def _deterministic_kernel_args (adj ):
51355098 if adj .det_meta is None or not adj .det_meta .needs_deterministic :
51365099 return []
51375100
51385101 from warp ._src .deterministic import kernel_raw_counter_param_names , kernel_raw_scatter_param_names # noqa: PLC0415
51395102
5140- hidden_args = [
5103+ det_args = [
51415104 "int _wp_det_phase" ,
51425105 "int _wp_det_debug" ,
51435106 "int* _wp_det_overflow" ,
51445107 ]
51455108 for target in adj .det_meta .counter_targets :
51465109 names = kernel_raw_counter_param_names (target )
5147- hidden_args .append (f"int* { names ['contrib' ]} " )
5148- hidden_args .append (f"int* { names ['prefix' ]} " )
5110+ det_args .append (f"wp::det_counter_buf_t { names ['buf' ]} " )
51495111 for target in adj .det_meta .scatter_targets :
51505112 names = kernel_raw_scatter_param_names (target )
5151- hidden_args .append (f"int64_t* { names ['keys' ]} " )
5152- hidden_args .append (f"{ target .value_ctype } * { names ['vals' ]} " )
5153- hidden_args .append (f"int* { names ['count' ]} " )
5154- hidden_args .append (f"int { names ['capacity' ]} " )
5155- return hidden_args
5113+ det_args .append (f"wp::det_scatter_buf_t<{ target .value_ctype } > { names ['buf' ]} " )
5114+ return det_args
51565115
51575116
51585117def _deterministic_kernel_locals (adj , device ):
@@ -5167,22 +5126,19 @@ def _deterministic_kernel_locals(adj, device):
51675126 ]
51685127 for target in adj .det_meta .counter_targets :
51695128 names = kernel_raw_counter_param_names (target )
5170- decls .append (f"wp::det_counter_buf { target .helper_name } {{ { names [ 'contrib' ] } , { names ['prefix' ] } } };" )
5129+ decls .append (f"auto& { target .helper_name } = { names ['buf' ] } ;" )
51715130 for target in adj .det_meta .scatter_targets :
51725131 names = kernel_raw_scatter_param_names (target )
5173- decls .append (
5174- f"wp::det_scatter_buf<{ target .value_ctype } > { target .helper_name } "
5175- f"{{{ names ['keys' ]} , { names ['vals' ]} , { names ['count' ]} , { names ['capacity' ]} }};"
5176- )
5132+ decls .append (f"auto& { target .helper_name } = { names ['buf' ]} ;" )
51775133 else :
51785134 decls = [
51795135 "wp::det_ctx det_ctx{0, 0, 0, nullptr};" ,
51805136 ]
51815137 for target in adj .det_meta .counter_targets :
5182- decls .append (f"wp::det_counter_buf { target .helper_name } {{nullptr, nullptr}};" )
5138+ decls .append (f"wp::det_counter_buf_t { target .helper_name } {{nullptr, nullptr}};" )
51835139 for target in adj .det_meta .scatter_targets :
51845140 decls .append (
5185- f"wp::det_scatter_buf <{ target .value_ctype } > { target .helper_name } {{nullptr, nullptr, nullptr, 0}};"
5141+ f"wp::det_scatter_buf_t <{ target .value_ctype } > { target .helper_name } {{nullptr, nullptr, nullptr, 0}};"
51865142 )
51875143 return "" .join (f" { line } \n " for line in decls )
51885144
@@ -5223,16 +5179,22 @@ def _include_deterministic_call_meta(adj, meta, bound_args):
52235179 get_or_create_counter_target (adj .det_registry , adj .det_meta , mapped_label , target .value_ctype )
52245180
52255181
5226- def _deterministic_call_hidden_args (meta , bound_args ):
5182+ def _deterministic_call_args (meta , bound_args ):
52275183 if meta is None or not meta .needs_deterministic :
52285184 return []
52295185
5230- hidden_args = ["det_ctx" ]
5186+ det_args = ["det_ctx" ]
52315187 for target in meta .counter_targets :
5232- hidden_args .append (f"det_{ _deterministic_map_target_label (target .array_var_label , bound_args )} " )
5188+ det_args .append (f"det_{ _deterministic_map_target_label (target .array_var_label , bound_args )} " )
52335189 for target in meta .scatter_targets :
5234- hidden_args .append (f"det_{ _deterministic_map_target_label (target .array_var_label , bound_args )} " )
5235- return hidden_args
5190+ det_args .append (f"det_{ _deterministic_map_target_label (target .array_var_label , bound_args )} " )
5191+ return det_args
5192+
5193+
5194+ def _cinit_expr (dtype ):
5195+ if hasattr (dtype , "cinit" ):
5196+ return dtype .cinit (requires_grad = False )
5197+ return f"{ Var .type_to_ctype (dtype )} {{}}"
52365198
52375199
52385200def codegen_kernel (kernel , device , options ):
@@ -5293,7 +5255,7 @@ def codegen_kernel(kernel, device, options):
52935255 for arg in adj .args :
52945256 forward_args .append (arg .ctype () + " var_" + arg .label )
52955257
5296- forward_args .extend (_deterministic_kernel_hidden_args (adj ))
5258+ forward_args .extend (_deterministic_kernel_args (adj ))
52975259
52985260 forward_body = ""
52995261 forward_body += _deterministic_kernel_locals (adj , device )
@@ -5324,7 +5286,7 @@ def codegen_kernel(kernel, device, options):
53245286 else :
53255287 reverse_args .append (arg .ctype () + " adj_" + arg .label )
53265288
5327- reverse_args .extend (_deterministic_kernel_hidden_args (adj ))
5289+ reverse_args .extend (_deterministic_kernel_args (adj ))
53285290
53295291 reverse_body = ""
53305292 reverse_body += _deterministic_kernel_locals (adj , device )
0 commit comments