Skip to content

Commit f207179

Browse files
author
Horde
committed
Clean deterministic ABI naming
1 parent d90079e commit f207179

6 files changed

Lines changed: 258 additions & 196 deletions

File tree

warp/_src/codegen.py

Lines changed: 52 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -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

51585117
def _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

52385200
def 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

Comments
 (0)