[CCCL] 瘦身 + 补全: 移除 cudax/python/libcudacxx-tests 冗余文件, 新增 c2h 测试助手 + cmake 构建系统 + 8 个 CUDA thrust examples
变更摘要:
- 删除: cudax/ (783 files, 7.2M) — 实验性组件,竞赛不需要
- 删除: python/ (226 files, 2.0M) — Python 绑定,竞赛不需要
- 删除: libcudacxx/{test,benchmarks,codegen,cmake,share} (4432 files, 31M)
保留: libcudacxx/include/ (1463 headers, cuda::std 编译依赖)
- 新增: c2h/ (27 files) — CUB Catch2 测试辅助头文件,编译 243 个测试必需
- 新增: cmake/ (29 files) — CCCL 原生 CMake 构建系统
- 新增: thrust/examples/cuda/ (7 files) + cpp_integration/ (1 file)
async_reduce, custom_temporary_allocation, explicit_cuda_stream,
global_device_vector, range_view, unwrap_pointer, wrap_pointer, device
结果: cccl_upstream 从 74M→35M (瘦身 53%), 核心内容 100% 保留:
27/27 tuning headers, 78 benchmarks, 243 tests,
60 thrust examples, 18 CUB examples, 全部编译头文件
This commit is contained in:
@@ -1,230 +0,0 @@
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def extract_function_name(template_content):
|
||||
"""
|
||||
Extract the function name from complex template parameters.
|
||||
Examples:
|
||||
- 'compute_residual(cuda::experimental::stf::stackable_ctx &, ...' -> 'compute_residual'
|
||||
- 'main::[lambda(unsigned long, T1, T2) (instance 1)]' -> 'main'
|
||||
"""
|
||||
# First, try to find a function-like pattern: name(args...)
|
||||
func_match = re.match(r"([a-zA-Z_][a-zA-Z0-9_]*)\s*\(", template_content)
|
||||
if func_match:
|
||||
return func_match.group(1)
|
||||
|
||||
# Handle patterns like "main::[lambda...]" - take part before "::"
|
||||
if "::" in template_content:
|
||||
first_part = template_content.split("::", 1)[0].strip()
|
||||
# Extract the identifier
|
||||
identifier_match = re.search(r"([a-zA-Z_][a-zA-Z0-9_]*)$", first_part)
|
||||
if identifier_match:
|
||||
return identifier_match.group(1)
|
||||
return first_part
|
||||
|
||||
# Fallback: take first identifier before comma
|
||||
first_part = template_content.split(",", 1)[0].strip()
|
||||
|
||||
# Extract just the identifier part (remove any type qualifiers)
|
||||
identifier_match = re.search(r"([a-zA-Z_][a-zA-Z0-9_]*)$", first_part)
|
||||
if identifier_match:
|
||||
return identifier_match.group(1)
|
||||
|
||||
return first_part
|
||||
|
||||
|
||||
def find_matching_bracket(text, start_pos, open_char="<", close_char=">"):
|
||||
"""Find the position of the matching closing bracket for nested brackets"""
|
||||
bracket_count = 1
|
||||
i = start_pos
|
||||
while i < len(text) and bracket_count > 0:
|
||||
if text[i] == open_char:
|
||||
bracket_count += 1
|
||||
elif text[i] == close_char:
|
||||
bracket_count -= 1
|
||||
i += 1
|
||||
return i - 1 if bracket_count == 0 else -1
|
||||
|
||||
|
||||
def simplify(line: str) -> str:
|
||||
# First, remove the long "void cuda::experimental::stf::reserved::" prefix and variations
|
||||
line = line.replace("void cuda::experimental::stf::reserved::", "")
|
||||
line = line.replace("cuda::experimental::stf::reserved::", "")
|
||||
|
||||
# Handle special cases first
|
||||
if "loop_redux_finalize" in line:
|
||||
line = re.sub(r".*loop_redux_finalize.*", "loop_redux_finalize", line)
|
||||
return line
|
||||
|
||||
# Handle condition_reset - remove angle brackets entirely
|
||||
line = re.sub(r"condition_reset<[^>]*>", "condition_reset", line)
|
||||
|
||||
# Handle loop_redux<...> patterns
|
||||
result = line
|
||||
pos = 0
|
||||
while True:
|
||||
match = re.search(r"loop_redux<", result[pos:])
|
||||
if not match:
|
||||
break
|
||||
start = pos + match.start()
|
||||
bracket_start = pos + match.end() - 1 # position of '<'
|
||||
bracket_end = find_matching_bracket(result, bracket_start + 1)
|
||||
if bracket_end != -1:
|
||||
inside = result[bracket_start + 1 : bracket_end]
|
||||
func_name = extract_function_name(inside)
|
||||
# Replace the entire loop_redux<...> with simplified version
|
||||
result = (
|
||||
result[:start] + f"loop_redux<{func_name}>" + result[bracket_end + 1 :]
|
||||
)
|
||||
pos = start + len(f"loop_redux<{func_name}>")
|
||||
else:
|
||||
pos = start + 1
|
||||
|
||||
# Handle regular loop<...> patterns
|
||||
pos = 0
|
||||
while True:
|
||||
match = re.search(r"loop<", result[pos:])
|
||||
if not match:
|
||||
break
|
||||
start = pos + match.start()
|
||||
bracket_start = pos + match.end() - 1 # position of '<'
|
||||
bracket_end = find_matching_bracket(result, bracket_start + 1)
|
||||
if bracket_end != -1:
|
||||
inside = result[bracket_start + 1 : bracket_end]
|
||||
func_name = extract_function_name(inside)
|
||||
# Replace the entire loop<...> with simplified version
|
||||
result = result[:start] + f"loop<{func_name}>" + result[bracket_end + 1 :]
|
||||
pos = start + len(f"loop<{func_name}>")
|
||||
else:
|
||||
pos = start + 1
|
||||
|
||||
# Handle condition_update_kernel<...> patterns (like loop patterns)
|
||||
pos = 0
|
||||
while True:
|
||||
match = re.search(r"condition_update_kernel<", result[pos:])
|
||||
if not match:
|
||||
break
|
||||
start = pos + match.start()
|
||||
bracket_start = pos + match.end() - 1 # position of '<'
|
||||
bracket_end = find_matching_bracket(result, bracket_start + 1)
|
||||
if bracket_end != -1:
|
||||
inside = result[bracket_start + 1 : bracket_end]
|
||||
func_name = extract_function_name(inside)
|
||||
# Replace the entire condition_update_kernel<...> with simplified version
|
||||
result = (
|
||||
result[:start]
|
||||
+ f"condition_update_kernel<{func_name}>"
|
||||
+ result[bracket_end + 1 :]
|
||||
)
|
||||
pos = start + len(f"condition_update_kernel<{func_name}>")
|
||||
else:
|
||||
pos = start + 1
|
||||
|
||||
# Remove function arguments - keep only allowed characters, stop at :: or (
|
||||
def clean_after_loop(match):
|
||||
loop_part = match.group(1) # the loop<...> or loop_redux<...> part
|
||||
after_loop = match.group(2) # everything after it
|
||||
|
||||
# Keep only letters, underscore, whitespace, and stop at :: or (
|
||||
cleaned = ""
|
||||
i = 0
|
||||
while i < len(after_loop):
|
||||
char = after_loop[i]
|
||||
if char in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_\t ":
|
||||
cleaned += char
|
||||
i += 1
|
||||
elif i < len(after_loop) - 1 and after_loop[i : i + 2] == "::":
|
||||
break # Stop at ::
|
||||
elif char == "(":
|
||||
break # Stop at (
|
||||
elif char == "\n":
|
||||
cleaned += char
|
||||
break # Stop at newline but include it
|
||||
else:
|
||||
i += 1 # Skip other characters but keep going
|
||||
|
||||
return loop_part + cleaned
|
||||
|
||||
# Apply argument cleanup to loop patterns and condition_update_kernel
|
||||
result = re.sub(
|
||||
r"((?:loop(?:_redux)?|condition_update_kernel)<[^>]+>)(.*)",
|
||||
clean_after_loop,
|
||||
result,
|
||||
)
|
||||
|
||||
# Also clean up condition_reset (which has no angle brackets after simplification)
|
||||
result = re.sub(r"(condition_reset)(.*)", clean_after_loop, result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def apply_cu_filt(input_text):
|
||||
"""Apply cu++filt to demangle C++ symbols"""
|
||||
try:
|
||||
# Run cu++filt to demangle C++ symbols
|
||||
process = subprocess.Popen(
|
||||
["cu++filt"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
stdout, stderr = process.communicate(input_text)
|
||||
|
||||
if process.returncode == 0:
|
||||
return stdout
|
||||
else:
|
||||
# If cu++filt fails, fall back to c++filt
|
||||
print(f"cu++filt failed: {stderr}, trying c++filt", file=sys.stderr)
|
||||
process = subprocess.Popen(
|
||||
["c++filt"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
stdout, stderr = process.communicate(input_text)
|
||||
if process.returncode == 0:
|
||||
return stdout
|
||||
else:
|
||||
print(
|
||||
f"c++filt also failed: {stderr}, using original text",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return input_text
|
||||
except FileNotFoundError:
|
||||
# If cu++filt is not available, try c++filt
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
["c++filt"],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
stdout, stderr = process.communicate(input_text)
|
||||
if process.returncode == 0:
|
||||
return stdout
|
||||
else:
|
||||
print(f"c++filt failed: {stderr}, using original text", file=sys.stderr)
|
||||
return input_text
|
||||
except FileNotFoundError:
|
||||
print(
|
||||
"Neither cu++filt nor c++filt found, using original text",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return input_text
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Read all input
|
||||
input_text = sys.stdin.read()
|
||||
|
||||
# First apply cu++filt to demangle symbols
|
||||
demangled_text = apply_cu_filt(input_text)
|
||||
|
||||
# Then apply our custom simplification to each line
|
||||
for line in demangled_text.splitlines(keepends=True):
|
||||
print(simplify(line), end="")
|
||||
Reference in New Issue
Block a user