"""
Batch fix for all non_contig CPPs:
1. aclrtFree null check + set nullptr (already done, skip if already fixed)
2. Output tensor scene excludes BROADCAST (min=2)
3. [FUZZ_PARAM] print: dtype, viewShape, storageShape, strides, offset, scene
4. [FUZZ_RESULT] print + ERROR label not overwriting ret + ret=-1 init per case
"""
import re
import os
import glob
SRC_DIR = "/home/30039325/Vector_fuzz_cpp_testing/turing_sec/aclnnAPI_fuzz/src/src_no_contiguous"
HELPER_FUNCS = '''
static const char* GetSceneName(int scene) {
switch(scene) {
case 0: return "CONTINUOUS";
case 1: return "BROADCAST";
case 2: return "SLICE";
case 3: return "ASSTRIDED";
case 4: return "STORAGE_PADDED";
case 5: return "TRANSPOSE";
default: return "UNKNOWN";
}
}
static const char* GetDtypeName(int dtype) {
switch(dtype) {
case 0: return "FLOAT";
case 1: return "FLOAT16";
case 2: return "INT8";
case 3: return "INT32";
case 4: return "UINT8";
case 6: return "INT16";
case 9: return "INT64";
case 11: return "BOOL";
case 12: return "DOUBLE";
case 27: return "BF16";
case 16: return "COMPLEX64";
default: return "UNKNOWN";
}
}
static void PrintShape(const char* name, const std::vector<int64_t>& shape) {
printf("%s=[", name);
for (size_t i = 0; i < shape.size(); i++) {
printf("%lld%s", (long long)shape[i], i < shape.size()-1 ? "," : "");
}
printf("]");
}
'''
def has_helper_funcs(content):
return 'GetSceneName' in content and 'GetDtypeName' in content
def inject_helper_funcs(content):
"""Inject helper functions after kDtypeNum line."""
if has_helper_funcs(content):
return content, False
pattern = r'(static int kDtypeNum\s*=\s*sizeof\(kDtypeEnum\)\s*/\s*sizeof\(kDtypeEnum\[0\]\)\s*;\s*\n)'
m = re.search(pattern, content)
if m:
content = content[:m.end()] + '\n' + HELPER_FUNCS + content[m.end():]
return content, True
pattern2 = r'(using namespace std;\s*\n)'
m2 = re.search(pattern2, content)
if m2:
content = content[:m2.end()] + '\n' + HELPER_FUNCS + content[m2.end():]
return content, True
return content, False
def fix_output_scene(content):
"""Fix output tensor scene to exclude BROADCAST (min=2)."""
changed = False
patterns = [
(r'ncOut\.scene\s*=\s*\*\(int\*\)\s*DTSetGetNumberRange\(&g_Element\[i\+\+\],\s*1,\s*1,\s*sceneMax,\s*"i"\)',
'ncOut.scene = *(int*)DTSetGetNumberRange(&g_Element[i++], 1, 2, sceneMax, "i")'),
(r'ncOut\.scene\s*=\s*\*\(int\*\)\s*DTSetGetNumberRange\(&g_Element\[i\+\+\],\s*1,\s*1,\s*\(dim_num\s*>=\s*2\s*\?\s*5\s*:\s*4\),\s*"i"\)',
'ncOut.scene = *(int*)DTSetGetNumberRange(&g_Element[i++], 1, 2, (dim_num >= 2 ? 5 : 4), "i")'),
]
for pat, repl in patterns:
if re.search(pat, content):
content = re.sub(pat, repl, content)
changed = True
pat_outnc = r'outNC\.scene\s*=\s*\*\(int\s*\*\)\s*DTSetGetNumberRange\(&g_Element\[i\+\+\],\s*1,\s*1,'
if re.search(pat_outnc, content):
content = re.sub(pat_outnc, 'outNC.scene = *(int *)DTSetGetNumberRange(&g_Element[i++], 1, 2,', content)
changed = True
for nc_var in ['ncOut', 'outNC', 'outputOutNC']:
calc_pat = f'CalcNonContiguousParams\\({nc_var}\\);'
clamp_pat = f'if ({nc_var}.scene < 2) {nc_var}.scene = 2;'
if re.search(calc_pat, content) and not re.search(clamp_pat, content):
content = re.sub(
f'(CalcNonContiguousParams\\({nc_var}\\);)',
f'\\1\n {clamp_pat}',
content
)
changed = True
return content, changed
def fix_error_label_and_result(content):
"""Fix ERROR label to not overwrite ret, add FUZZ_RESULT, add ret=-1 init."""
changed = False
is_checkret = 'checkRet = CheckAndLog' in content
if is_checkret:
if 'ret = -1;' not in content:
pat = r'(void\*\s*workspaceAddr\s*=\s*nullptr;\s*\n)'
m = re.search(pat, content)
if m:
content = content[:m.end()] + ' ret = -1;\n' + content[m.end():]
changed = True
return content, changed
if 'syncRet' not in content:
old_error = r'ERROR:\n\s*ret\s*=\s*aclrtSynchronizeStream\(stream\);\n\s*printf\("end \\n"\);\n\s*CheckAndLog\(ret\);'
new_error = 'ERROR:\n {\n aclError syncRet = aclrtSynchronizeStream(stream);\n (void)syncRet;\n }\n printf("end \\n");\n CheckAndLog(ret);'
if re.search(old_error, content):
content = re.sub(old_error, new_error, content)
changed = True
if 'FUZZ_RESULT' not in content:
old_check = r'(CheckAndLog\(ret\);\n)'
new_check = '\\1 if (ret == 0) { success_count++; } else { faild_count++; }\n printf("[FUZZ_RESULT] case_%d: %s, ret=%d\\n", fuzzi, ret == 0 ? "success" : "faild", ret);\n'
if re.search(old_check, content):
content = re.sub(old_check, new_check, content)
changed = True
if 'ret = -1;' not in content:
pat = r'(void\*\s*workspaceAddr\s*=\s*nullptr;\s*\n)'
m = re.search(pat, content)
if m:
content = content[:m.end()] + ' ret = -1;\n' + content[m.end():]
changed = True
return content, changed
def add_fuzz_param_print(content):
"""Add [FUZZ_PARAM] print after CalcNonContiguousParams for output tensor."""
changed = False
if 'FUZZ_PARAM' in content and 'viewShape' in content and 'storageShape' in content:
return content, False
pat_ncout = r'(CalcNonContiguousParams\(ncOut\);\s*\n\s*(?:if \(ncOut\.scene < 2\) ncOut\.scene = 2;\s*\n\s*)?long long outStorageSize = GetShapeSize\(ncOut\.storageShape\);\s*\n)'
m = re.search(pat_ncout, content)
if m and 'FUZZ_PARAM' not in content[:m.end()+100]:
pat_nc = r'CalcNonContiguousParams\(nc\);\s*\n\s*long long selfStorageSize = GetShapeSize\(nc\.storageShape\);'
m_nc = re.search(pat_nc, content)
if m_nc:
param_print = (
'\n'
' printf("[FUZZ_PARAM] dtype=%s, ", GetDtypeName((int)inputDtype));\n'
' printf("self: "); PrintShape("viewShape", nc.viewShape); PrintShape(",storageShape", nc.storageShape);\n'
' printf(", strides=["); for (size_t j = 0; j < nc.strides.size(); j++) { printf("%lld%s", (long long)nc.strides[j], j < nc.strides.size()-1 ? "," : ""); } printf("]");\n'
' printf(", offset=%lld, scene=%s(%d)", (long long)nc.offset, GetSceneName(nc.scene), nc.scene);\n'
' printf(" | out: "); PrintShape("viewShape", ncOut.viewShape); PrintShape(",storageShape", ncOut.storageShape);\n'
' printf(", strides=["); for (size_t j = 0; j < ncOut.strides.size(); j++) { printf("%lld%s", (long long)ncOut.strides[j], j < ncOut.strides.size()-1 ? "," : ""); } printf("]");\n'
' printf(", offset=%lld, scene=%s(%d)\\n", (long long)ncOut.offset, GetSceneName(ncOut.scene), ncOut.scene);\n'
)
content = content[:m.end()] + param_print + content[m.end():]
changed = True
return content, changed
def fix_file(filepath):
"""Fix a single CPP file with all 4 modifications."""
with open(filepath, 'r', encoding='utf-8', errors='replace') as f:
content = f.read()
changed = False
content, c = inject_helper_funcs(content)
if c:
changed = True
content, c = fix_output_scene(content)
if c:
changed = True
content, c = add_fuzz_param_print(content)
if c:
changed = True
content, c = fix_error_label_and_result(content)
if c:
changed = True
if changed:
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
return changed
def main():
cpp_files = sorted(glob.glob(os.path.join(SRC_DIR, "*_non_contig.cpp")))
total = len(cpp_files)
fixed = 0
skipped = 0
errors = 0
print(f"Total files: {total}")
print(f"Source dir: {SRC_DIR}")
print()
for i, filepath in enumerate(cpp_files):
filename = os.path.basename(filepath)
try:
if fix_file(filepath):
fixed += 1
print(f"[{i+1}/{total}] FIXED: {filename}")
else:
skipped += 1
except Exception as e:
errors += 1
print(f"[{i+1}/{total}] ERROR: {filename} - {e}")
print()
print(f"=== Summary ===")
print(f"Total: {total}")
print(f"Fixed: {fixed}")
print(f"Skipped (already fixed): {skipped}")
print(f"Errors: {errors}")
if __name__ == '__main__':
main()