From e81be87c4fbb515edbc1c11fcff6f81b97fac83b Mon Sep 17 00:00:00 2001 From: Cloud Han Date: Mon, 8 May 2023 10:15:10 +0800 Subject: [PATCH 1/3] Add support for calling msvc with command file --- .../windows/msvc_wrapper_for_nvcc.py.tpl | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl index 447e5ba7ec96e..b8bbff2f0bcf0 100644 --- a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl +++ b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl @@ -193,6 +193,18 @@ def InvokeNvcc(argv, log=False): proc.wait() return proc.returncode + +def ProcessFlagForCommandFile(flag): + if flag.startswith("/D") or flag.startswith("-D"): + # We need to re-escape /DFOO="BAR" as /DFOO=\"BAR\", so that we get + # `#define FOO "BAR"` after expansion as a string literal define + if flag.endswith('"') and not flag.endswith('\\"'): + flag = '\\"'.join(flag.split('"', 1)) + flag = '\\"'.join(flag.rsplit('"', 1)) + return flag + return flag + + def main(): parser = ArgumentParser() parser.add_argument('-x', nargs=1) @@ -213,7 +225,18 @@ def main(): if not flag.startswith(('--cuda_log')) and not flag.startswith(('-nvcc_options'))] - return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) + output = [flag for flag in cpu_compiler_flags if flag.startswith("/Fo")] + + # Store command line options in a file to avoid hitting the character limit. + if len(output) == 1: + commandfile_path = output[0][3:] + ".msvc_params" + commandfile = open(commandfile_path, "w") + cpu_compiler_flags = [ProcessFlagForCommandFile(flag) for flag in cpu_compiler_flags] + commandfile.write("\n".join(cpu_compiler_flags)) + commandfile.close() + return subprocess.call([CPU_COMPILER, "@" + commandfile_path]) + else: + return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) if __name__ == '__main__': sys.exit(main()) From fcdd97027e0d8dff3bda94eb1b3a5f109ffbb9c1 Mon Sep 17 00:00:00 2001 From: Cloud Han Date: Mon, 8 May 2023 10:18:26 +0800 Subject: [PATCH 2/3] Add support for calling msvc wrapper with command file --- .../gpus/crosstool/cc_toolchain_config.bzl.tpl | 7 +------ .../crosstool/windows/msvc_wrapper_for_nvcc.py.tpl | 11 +++++++++++ third_party/tsl/third_party/gpus/cuda_configure.bzl | 7 ++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl b/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl index c79ad6c73928b..ffa305c772e88 100644 --- a/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl +++ b/third_party/tsl/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl @@ -599,6 +599,7 @@ def _features(cpu, compiler, ctx): ] elif cpu == "x64_windows": return [ + feature(name = "compiler_param_file"), feature(name = "no_legacy_features"), feature( name = "common_flags", @@ -623,12 +624,6 @@ def _features(cpu, compiler, ctx): flag_set( actions = all_compile_actions(), flag_groups = [ - flag_group( - flags = [ - "-B", - "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py", - ], - ), _nologo(), flag_group( flags = [ diff --git a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl index b8bbff2f0bcf0..cf2ae1669b2d7 100644 --- a/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl +++ b/third_party/tsl/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl @@ -193,6 +193,16 @@ def InvokeNvcc(argv, log=False): proc.wait() return proc.returncode +def ExpandParamsFileForArgv(): + new_argv = [] + for arg in sys.argv: + if arg.startswith("@"): + with open(arg.strip("@")) as f: + new_argv.extend([l.strip() for l in f.readlines()]) + else: + new_argv.append(arg) + + sys.argv = new_argv def ProcessFlagForCommandFile(flag): if flag.startswith("/D") or flag.startswith("-D"): @@ -206,6 +216,7 @@ def ProcessFlagForCommandFile(flag): def main(): + ExpandParamsFileForArgv() parser = ArgumentParser() parser.add_argument('-x', nargs=1) parser.add_argument('--cuda_log', action='store_true') diff --git a/third_party/tsl/third_party/gpus/cuda_configure.bzl b/third_party/tsl/third_party/gpus/cuda_configure.bzl index 1f94be8c7e41b..1ce2e9e6fbeb3 100644 --- a/third_party/tsl/third_party/gpus/cuda_configure.bzl +++ b/third_party/tsl/third_party/gpus/cuda_configure.bzl @@ -168,7 +168,7 @@ def _get_win_cuda_defines(repository_ctx): ), ) - msvc_cl_path = get_python_bin(repository_ctx) + msvc_cl_path = "windows/msvc_wrapper_for_nvcc.bat" msvc_ml_path = find_msvc_tool(repository_ctx, vc_path, "ml64.exe").replace( "\\", "/", @@ -1301,6 +1301,11 @@ def _create_local_cuda_repository(repository_ctx): tpl_paths["crosstool:clang/bin/crosstool_wrapper_driver_is_not_gcc"], wrapper_defines, ) + repository_ctx.file( + "crosstool/windows/msvc_wrapper_for_nvcc.bat", + content = "@echo OFF\n{} -B external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py %*".format( + get_python_bin(repository_ctx)) + ) repository_ctx.template( "crosstool/windows/msvc_wrapper_for_nvcc.py", tpl_paths["crosstool:windows/msvc_wrapper_for_nvcc.py"], From 6865c404d5314f732b5e05141f514d2fc24fed11 Mon Sep 17 00:00:00 2001 From: Cloud Han Date: Mon, 8 May 2023 10:26:48 +0800 Subject: [PATCH 3/3] Sync changes from xla/third_party/tsl/third_party/gpus to xla/third_party/gpus --- .../crosstool/cc_toolchain_config.bzl.tpl | 7 +--- .../windows/msvc_wrapper_for_nvcc.py.tpl | 36 ++++++++++++++++++- third_party/gpus/cuda_configure.bzl | 7 +++- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl b/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl index c79ad6c73928b..ffa305c772e88 100644 --- a/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl +++ b/third_party/gpus/crosstool/cc_toolchain_config.bzl.tpl @@ -599,6 +599,7 @@ def _features(cpu, compiler, ctx): ] elif cpu == "x64_windows": return [ + feature(name = "compiler_param_file"), feature(name = "no_legacy_features"), feature( name = "common_flags", @@ -623,12 +624,6 @@ def _features(cpu, compiler, ctx): flag_set( actions = all_compile_actions(), flag_groups = [ - flag_group( - flags = [ - "-B", - "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py", - ], - ), _nologo(), flag_group( flags = [ diff --git a/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl b/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl index 447e5ba7ec96e..cf2ae1669b2d7 100644 --- a/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl +++ b/third_party/gpus/crosstool/windows/msvc_wrapper_for_nvcc.py.tpl @@ -193,7 +193,30 @@ def InvokeNvcc(argv, log=False): proc.wait() return proc.returncode +def ExpandParamsFileForArgv(): + new_argv = [] + for arg in sys.argv: + if arg.startswith("@"): + with open(arg.strip("@")) as f: + new_argv.extend([l.strip() for l in f.readlines()]) + else: + new_argv.append(arg) + + sys.argv = new_argv + +def ProcessFlagForCommandFile(flag): + if flag.startswith("/D") or flag.startswith("-D"): + # We need to re-escape /DFOO="BAR" as /DFOO=\"BAR\", so that we get + # `#define FOO "BAR"` after expansion as a string literal define + if flag.endswith('"') and not flag.endswith('\\"'): + flag = '\\"'.join(flag.split('"', 1)) + flag = '\\"'.join(flag.rsplit('"', 1)) + return flag + return flag + + def main(): + ExpandParamsFileForArgv() parser = ArgumentParser() parser.add_argument('-x', nargs=1) parser.add_argument('--cuda_log', action='store_true') @@ -213,7 +236,18 @@ def main(): if not flag.startswith(('--cuda_log')) and not flag.startswith(('-nvcc_options'))] - return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) + output = [flag for flag in cpu_compiler_flags if flag.startswith("/Fo")] + + # Store command line options in a file to avoid hitting the character limit. + if len(output) == 1: + commandfile_path = output[0][3:] + ".msvc_params" + commandfile = open(commandfile_path, "w") + cpu_compiler_flags = [ProcessFlagForCommandFile(flag) for flag in cpu_compiler_flags] + commandfile.write("\n".join(cpu_compiler_flags)) + commandfile.close() + return subprocess.call([CPU_COMPILER, "@" + commandfile_path]) + else: + return subprocess.call([CPU_COMPILER] + cpu_compiler_flags) if __name__ == '__main__': sys.exit(main()) diff --git a/third_party/gpus/cuda_configure.bzl b/third_party/gpus/cuda_configure.bzl index 1f94be8c7e41b..1ce2e9e6fbeb3 100644 --- a/third_party/gpus/cuda_configure.bzl +++ b/third_party/gpus/cuda_configure.bzl @@ -168,7 +168,7 @@ def _get_win_cuda_defines(repository_ctx): ), ) - msvc_cl_path = get_python_bin(repository_ctx) + msvc_cl_path = "windows/msvc_wrapper_for_nvcc.bat" msvc_ml_path = find_msvc_tool(repository_ctx, vc_path, "ml64.exe").replace( "\\", "/", @@ -1301,6 +1301,11 @@ def _create_local_cuda_repository(repository_ctx): tpl_paths["crosstool:clang/bin/crosstool_wrapper_driver_is_not_gcc"], wrapper_defines, ) + repository_ctx.file( + "crosstool/windows/msvc_wrapper_for_nvcc.bat", + content = "@echo OFF\n{} -B external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py %*".format( + get_python_bin(repository_ctx)) + ) repository_ctx.template( "crosstool/windows/msvc_wrapper_for_nvcc.py", tpl_paths["crosstool:windows/msvc_wrapper_for_nvcc.py"],