"""
gen_multithread_from_nc.py
从已有 non_contig CPP 机械转换生成 multithread CPP(ascendc-fuzz-multithread-cpp-gen 规则)。
转换规则(与框架已验证模板一致):
M1 入口函数:extern "C" int {api}_fuzz(int argc, char *argv[], aclrtContext context)(整块替换旧入口)
M2 Normal 函数签名加 aclrtContext context;Init(deviceId,...) 替换为
aclrtSetCurrentContext(context) + aclrtCreateStream(&stream)
M4 scene 范围 0~5(含 CONTINUOUS/BROADCAST):scene 下界 2 → 0
M5 函数末尾 aclrtDestroyStream(stream),不销毁 context/device(main_multithread 统一管理)
M6 日志名 non_contig → multithread
用法:
python gen_multithread_from_nc.py <nc.cpp> <out.cpp> <apiName>
"""
import re
import sys
def convert(nc_path, out_path, api):
c = open(nc_path, errors='ignore').read()
c = re.sub(rf'int {re.escape(api)}_non_contig(_Normal)?\(int fuzz_num\)',
f'int {api}_multithread_Normal(int fuzz_num, aclrtContext context)', c)
c = re.sub(rf'{re.escape(api)}_non_contig(_Normal)?\(fuzz_num\)',
f'{api}_multithread_Normal(fuzz_num, context)', c)
c = re.sub(r'auto ret = Init\(deviceId, &context, &stream\);',
lambda m: ('auto ret = aclrtSetCurrentContext(context);\n'
' CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetCurrentContext failed. ERROR: %d' + r'\n' + '", ret); return ret);\n'
' ret = aclrtCreateStream(&stream);\n'
' CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d' + r'\n' + '", ret); return ret);'),
c)
c = re.sub(r'DTSetGetNumberRange\(&g_Element\[i\+\+\], 2, 2, \(ndim >= 2 \? 5 : 4\), "i"\)',
'DTSetGetNumberRange(&g_Element[i++], 2, 0, (ndim >= 2 ? 5 : 4), "i")', c)
c = c.replace(f'"{api}_non_contig"', f'"{api}_multithread"')
c = re.sub(r'aclrtDestroyStream\(stream\);\s*aclrtDestroyContext\(context\);\s*aclrtResetDevice\(deviceId\);\s*aclFinalize\(\);',
'aclrtDestroyStream(stream);', c)
new_entry = f'''extern "C" int {api}_fuzz(int argc, char *argv[], aclrtContext context)
{{
int fuzz_num = MAXFUZZNUMBER;
if (argc > 2) {{ fuzz_num = atoi(argv[2]); }}
printf("fuzz_num %d \\n", fuzz_num);
printf("{api}_multithread_Normal :%d \\n", {api}_multithread_Normal(fuzz_num, context));
return 0;
}}
'''
m = re.search(rf'(extern "C"\s+)?int {re.escape(api)}_non_contig_fuzz\(', c)
if m:
c = c[:m.start()] + new_entry
else:
c = c.rstrip() + '\n\n' + new_entry
open(out_path, 'w').write(c)
print(f'Transformed: {nc_path} -> {out_path}')
if __name__ == '__main__':
convert(sys.argv[1], sys.argv[2], sys.argv[3])