diff --git a/script/convert_miopen_driver_commands.py b/script/convert_miopen_driver_commands.py new file mode 100755 index 0000000000..4c32fd90dc --- /dev/null +++ b/script/convert_miopen_driver_commands.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import os + +def parse_miopen_command(miopen_cmd): + """Parse MIOpen driver command and extract parameters""" + # Remove 'convbfp16' or similar prefix and split into arguments + parts = miopen_cmd.strip().split() + if not parts: + return None + + # Skip the command name (convbfp16, convfp16, etc.) + args = parts[1:] if parts[0].startswith('conv') else parts + + params = {} + i = 0 + while i < len(args): + if args[i].startswith('-'): + key = args[i] + if i + 1 < len(args) and not args[i + 1].startswith('-'): + params[key] = args[i + 1] + i += 2 + else: + params[key] = True + i += 1 + else: + i += 1 + + return params + +def determine_operation_type(params): + """Determine the operation type based on MIOpen parameters""" + # TODO: Current data is for bwd weight. + return "grouped_conv_bwd_weight" + +def convert_miopen_to_ck_profiler(miopen_cmd): + """Convert MIOpen driver command to CK profiler command""" + params = parse_miopen_command(miopen_cmd) + if not params: + return None + + # Determine operation type + operation = determine_operation_type(params) + + data_type = 5 # BF16 + layout = 2 # channels last + verification = 1 # with verification + init_method = 2 # uniform data + print_output = 0 # no print output + time_kernel = 1 # time kernel + n_dim = 2 # 2D convolution by default + + # Build CK profiler command + ck_cmd = [operation, str(data_type), str(layout), str(verification), + str(init_method), str(print_output), str(time_kernel), str(n_dim)] + + # Add tensor dimensions + G = params.get('-g', '1') + N = params.get('-n', '1') + K = params.get('-k', '1') + C = params.get('-c', '1') + + ck_cmd.extend([G, N, K, C]) + + Y = params.get('-y', '1') + X = params.get('-x', '1') + ck_cmd.extend([Y, X]) + + # Input dimensions + Hi = params.get('-H', '1') + Wi = params.get('-W', '1') + ck_cmd.extend([Hi, Wi]) + + # Stride + stride_h = params.get('-u', '1') + stride_w = params.get('-v', '1') + ck_cmd.extend([stride_h, stride_w]) + + # Dilation + dilation_h = params.get('-l', '1') + dilation_w = params.get('-j', '1') + ck_cmd.extend([dilation_h, dilation_w]) + + # Padding + pad_h = params.get('-p', '0') + pad_w = params.get('-q', '0') + ck_cmd.extend([pad_h, pad_w, pad_h, pad_w]) # Assuming symmetric padding + + # Split-K + split_k = "all" + ck_cmd.append(split_k) + + return ' '.join(ck_cmd) + +def convert_file(input_file, output_file): + """Convert MIOpen commands from input file and save CK profiler commands to output file""" + converted_commands = [] + failed_conversions = [] + + try: + with open(input_file, 'r') as f: + lines = f.readlines() + + # Skip header line if present + start_idx = 0 + if lines and (lines[0].strip().lower() == 'shape' or 'conv' not in lines[0].lower()): + start_idx = 1 + + for line_num, line in enumerate(lines[start_idx:], start_idx + 1): + line = line.strip() + if not line or line.startswith('#'): + continue + + ck_cmd = convert_miopen_to_ck_profiler(line) + if ck_cmd: + converted_commands.append(ck_cmd) + else: + failed_conversions.append((line_num, line)) + + # Write converted commands to output file + with open(output_file, 'w') as f: + for cmd in converted_commands: + f.write(cmd + '\n') + + print(f"Conversion completed successfully!") + print(f"Input file: {input_file}") + print(f"Output file: {output_file}") + print(f"Converted {len(converted_commands)} commands") + + if failed_conversions: + print(f"\nFailed to convert {len(failed_conversions)} commands:") + for line_num, line in failed_conversions[:5]: # Show first 5 failures + print(f" Line {line_num}: {line[:80]}...") + if len(failed_conversions) > 5: + print(f" ... and {len(failed_conversions) - 5} more") + + return True + + except FileNotFoundError: + print(f"Error: Input file '{input_file}' not found") + return False + except Exception as e: + print(f"Error during conversion: {e}") + return False + +def generate_output_filename(input_file): + """Generate output filename based on input filename""" + base_name = os.path.splitext(input_file)[0] + return f"{base_name}_ck_profiler.txt" + +def parse_arguments(): + """Parse command line arguments""" + parser = argparse.ArgumentParser( + description='Convert MIOpen driver commands to CK profiler commands', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog="""Examples: + python3 convert_miopen_driver_to_profiler.py miopen_commands.txt + python3 convert_miopen_driver_to_profiler.py miopen_commands.txt -o ck_commands.txt + python3 convert_miopen_driver_to_profiler.py --validate miopen_commands.txt""" + ) + + parser.add_argument('input_file', + help='Input file containing MIOpen driver commands') + parser.add_argument('-o', '--output', + help='Output file for CK profiler commands (default: auto-generated)') + parser.add_argument('--validate', action='store_true', + help='Validate converted commands (dry run)') + + return parser.parse_args() + +def main(): + args = parse_arguments() + + # Check if input file exists + if not os.path.exists(args.input_file): + print(f"Error: Input file '{args.input_file}' does not exist") + sys.exit(1) + + # Generate output filename if not provided + output_file = args.output if args.output else generate_output_filename(args.input_file) + + # Validate mode - just show what would be converted + if args.validate: + print("Validation mode - showing first 5 conversions:") + try: + with open(args.input_file, 'r') as f: + lines = f.readlines()[:6] # Header + 5 commands + + start_idx = 1 if lines and 'conv' not in lines[0].lower() else 0 + + for i, line in enumerate(lines[start_idx:start_idx+5]): + line = line.strip() + if not line: + continue + + ck_cmd = convert_miopen_to_ck_profiler(line) + print(f"\n{i+1}. MIOpen: {line[:80]}{'...' if len(line) > 80 else ''}") + print(f" CK: {ck_cmd if ck_cmd else 'CONVERSION FAILED'}") + + print(f"\nWould write to: {output_file}") + except Exception as e: + print(f"Validation error: {e}") + + return + + # Perform the actual conversion + success = convert_file(args.input_file, output_file) + + if success: + print(f"\nConversion completed! You can now use the converted commands with:") + print(f" # For individual command testing:") + print(f" ./profiler/ck_tile/ckTileProfiler ") + print(f" ") + print(f" # For batch processing, you can create a script that reads from {os.path.basename(output_file)}") + else: + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file