Skip to content

Commit 330b76a

Browse files
committed
Fix path issues on Windows and fix comments
1 parent 240d284 commit 330b76a

File tree

3 files changed

+136
-99
lines changed

3 files changed

+136
-99
lines changed

build/build.py

Lines changed: 114 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ def add_python_version_argument(parser: argparse.ArgumentParser):
6565
type=str,
6666
choices=["3.10", "3.11", "3.12", "3.13"],
6767
default=f"{sys.version_info.major}.{sys.version_info.minor}",
68-
help="Hermetic Python version to use",
68+
help=
69+
"""
70+
Hermetic Python version to use. Default is to use the version of the
71+
Python binary that executed the CLI.
72+
""",
6973
)
7074

7175

@@ -74,7 +78,11 @@ def add_cuda_version_argument(parser: argparse.ArgumentParser):
7478
"--cuda_version",
7579
type=str,
7680
default=None,
77-
help="Hermetic CUDA version to use",
81+
help=
82+
"""
83+
Hermetic CUDA version to use. Default is to use the version specified
84+
in the .bazelrc.
85+
""",
7886
)
7987

8088

@@ -83,7 +91,11 @@ def add_cudnn_version_argument(parser: argparse.ArgumentParser):
8391
"--cudnn_version",
8492
type=str,
8593
default=None,
86-
help="Hermetic cuDNN version to use",
94+
help=
95+
"""
96+
Hermetic cuDNN version to use. Default is to use the version specified
97+
in the .bazelrc.
98+
""",
8799
)
88100

89101

@@ -100,7 +112,11 @@ def add_cuda_compute_capabilities_argument(parser: argparse.ArgumentParser):
100112
"--cuda_compute_capabilities",
101113
type=str,
102114
default=None,
103-
help="A comma-separated list of CUDA compute capabilities to support.",
115+
help=
116+
"""
117+
A comma-separated list of CUDA compute capabilities to support. Default
118+
is to use the values specified in the .bazelrc.
119+
""",
104120
)
105121

106122

@@ -110,8 +126,8 @@ def add_build_cuda_with_clang_argument(parser: argparse.ArgumentParser):
110126
action="store_true",
111127
help="""
112128
Should CUDA code be compiled using Clang? The default behavior is to
113-
compile CUDA with NVCC. Ignored if --use_ci_bazelrc_flags is set, we
114-
always build CUDA with NVCC in CI builds.
129+
compile CUDA with NVCC. Ignored if --use_ci_bazelrc_flags is set, CI
130+
builds always build CUDA with NVCC in CI builds.
115131
""",
116132
)
117133

@@ -169,21 +185,23 @@ def add_global_arguments(parser: argparse.ArgumentParser):
169185

170186
parser.add_argument(
171187
"--bazel_startup_options",
172-
type=str,
173-
default="",
188+
action="append",
189+
default=[],
174190
help="""
175-
Space separated list of additional startup options to pass to Bazel
176-
E.g. --bazel_startup_options='--nobatch --noclient_debug'
191+
Additional startup options to pass to Bazel, can be specified multiple
192+
times to pass multiple options.
193+
E.g. --bazel_startup_options='--nobatch'
177194
""",
178195
)
179196

180197
parser.add_argument(
181198
"--bazel_build_options",
182-
type=str,
183-
default="",
199+
action="append",
200+
default=[],
184201
help="""
185-
Space separated list of additional build options to pass to Bazel
186-
E.g. --bazel_build_options='--local_resources=HOST_CPUS --nosandbox_debug'
202+
Additional build options to pass to Bazel, can be specified multiple
203+
times to pass multiple options.
204+
E.g. --bazel_build_options='--local_resources=HOST_CPUS'
187205
""",
188206
)
189207

@@ -207,7 +225,8 @@ def add_artifact_subcommand_global_arguments(parser: argparse.ArgumentParser):
207225
action="store_true",
208226
help="""
209227
When set, the CLI will assume the build is being run in CI or CI like
210-
environment and will use the "rbe_/ci_" configs in the .bazelrc.
228+
environment and will use the "rbe_/ci_" configs in the .bazelrc. These
229+
configs apply release features and set a custom C++ Clang toolchain.
211230
""",
212231
)
213232

@@ -218,9 +237,12 @@ def add_artifact_subcommand_global_arguments(parser: argparse.ArgumentParser):
218237
)
219238

220239
parser.add_argument(
221-
"--enable_mkl_dnn",
240+
"--disable_mkl_dnn",
222241
action="store_true",
223-
help="Enables MKL-DNN.",
242+
help="""
243+
Disables MKL-DNN. Ignored if --use_ci_bazelrc_flags is set, CI bazelrc
244+
flags enable MKL-DNN as default.
245+
""",
224246
)
225247

226248
parser.add_argument(
@@ -230,20 +252,17 @@ def add_artifact_subcommand_global_arguments(parser: argparse.ArgumentParser):
230252
)
231253

232254
parser.add_argument(
233-
"--enable_release_cpu_features",
234-
action="store_true",
235-
help="""
236-
Enables CPU features that should be enabled for a release build, which
237-
on x86-64 architectures enables AVX.
238-
""",
239-
)
240-
241-
parser.add_argument(
242-
"--enable_native_cpu_features",
243-
action="store_true",
255+
"--target_cpu_features",
256+
choices=["release", "native", "default"],
257+
default="release",
244258
help="""
245-
Enables -march=native, which generates code targeted to use all features
246-
of the current machine.
259+
What CPU features should we target? Release enables CPU features that
260+
should be enabled for a release build, which on x86-64 architectures
261+
enables AVX. Native enables -march=native, which generates code targeted
262+
to use all features of the current machine. Default means don't opt-in
263+
to any architectural features and use whatever the C compiler generates
264+
by default. Ignored if --use_ci_bazelrc_flags is set, CI bazelrc flags
265+
enable release CPU features as default.
247266
""",
248267
)
249268

@@ -252,8 +271,8 @@ def add_artifact_subcommand_global_arguments(parser: argparse.ArgumentParser):
252271
type=str,
253272
default="",
254273
help="""
255-
Path to the Clang binary to use. Ignored if --use_ci_bazelrc_flags is
256-
set as we use a custom Clang toolchain in that case.
274+
Path to the Clang binary to use. Ignored if --use_ci_bazelrc_flags, CI
275+
bazelrc flags set a custom Clang toolchain.
257276
""",
258277
)
259278

@@ -270,17 +289,18 @@ def add_artifact_subcommand_global_arguments(parser: argparse.ArgumentParser):
270289
parser.add_argument(
271290
"--output_path",
272291
type=str,
273-
default=os.environ.get(
274-
"JAXCI_OUTPUT_DIR", os.path.join(os.getcwd(), "dist")
275-
),
292+
default=os.path.join(os.getcwd(), "dist"),
276293
help="Directory to which the JAX wheel packages should be written.",
277294
)
278295

279-
280-
def parse_and_append_bazel_options(bazel_command: command.CommandBuilder, bazel_options: str):
281-
"""Parses the bazel options and appends them to the bazel command."""
282-
for option in bazel_options.split(" "):
283-
bazel_command.append(option)
296+
parser.add_argument(
297+
"--configure_only",
298+
action="store_true",
299+
help="""
300+
If true, writes the Bazel options to the .jax_configure.bazelrc file but
301+
does not build the artifacts. Ignored if --use_ci_bazelrc_flags is set.
302+
""",
303+
)
284304

285305

286306
async def main():
@@ -394,7 +414,8 @@ async def main():
394414
logging.debug(
395415
"Additional Bazel startup options: %s", args.bazel_startup_options
396416
)
397-
parse_and_append_bazel_options(bazel_command, args.bazel_startup_options)
417+
for option in args.bazel_startup_options:
418+
bazel_command.append(option)
398419

399420
bazel_command.append("run")
400421

@@ -409,7 +430,8 @@ async def main():
409430
logging.debug(
410431
"Using additional build options: %s", args.bazel_build_options
411432
)
412-
parse_and_append_bazel_options(bazel_command, args.bazel_build_options)
433+
for option in args.bazel_build_options:
434+
bazel_command.append(option)
413435

414436
if args.nightly_update:
415437
logging.debug(
@@ -445,15 +467,20 @@ async def main():
445467
else:
446468
clang_path = args.clang_path or utils.get_clang_path_or_exit()
447469
logging.debug("Using Clang as the compiler, clang path: %s", clang_path)
448-
bazel_command.append(f"--action_env CLANG_COMPILER_PATH={clang_path}")
449-
bazel_command.append(f"--repo_env CC={clang_path}")
450-
bazel_command.append(f"--repo_env BAZEL_COMPILER={clang_path}")
470+
# Use double quotes around clang path to avoid path issues on Windows.
471+
bazel_command.append(f'--action_env=CLANG_COMPILER_PATH="{clang_path}"')
472+
bazel_command.append(f'--repo_env=CC="{clang_path}"')
473+
bazel_command.append(f'--repo_env=BAZEL_COMPILER="{clang_path}"')
451474
bazel_command.append("--config=clang")
452475

476+
if not args.disable_mkl_dnn:
477+
logging.debug("Enabling MKL DNN")
478+
bazel_command.append("--config=mkl_open_source_only")
479+
453480
if "cuda" in args.command:
454481
bazel_command.append("--config=cuda")
455482
bazel_command.append(
456-
f"--action_env=CLANG_CUDA_COMPILER_PATH={clang_path}"
483+
f'--action_env=CLANG_CUDA_COMPILER_PATH="{clang_path}"'
457484
)
458485
if args.build_cuda_with_clang:
459486
logging.debug("Building CUDA with Clang")
@@ -462,40 +489,37 @@ async def main():
462489
logging.debug("Building CUDA with NVCC")
463490
bazel_command.append("--config=build_cuda_with_nvcc")
464491

492+
if args.target_cpu_features == "release":
493+
logging.debug(
494+
"Using release cpu features: --config=avx_%s",
495+
"windows" if os_name == "windows" else "posix",
496+
)
497+
if arch in ["x86_64", "AMD64"]:
498+
bazel_command.append(
499+
"--config=avx_windows"
500+
if os_name == "windows"
501+
else "--config=avx_posix"
502+
)
503+
elif args.target_cpu_features == "native":
504+
if os_name == "windows":
505+
logger.warning(
506+
"--target_cpu_features=native is not supported on Windows;"
507+
" ignoring."
508+
)
509+
else:
510+
logging.debug("Using native cpu features: --config=native_arch_posix")
511+
bazel_command.append("--config=native_arch_posix")
512+
else:
513+
logging.debug("Using default cpu features")
514+
465515
if args.target_cpu:
466516
logging.debug("Target CPU: %s", args.target_cpu)
467517
bazel_command.append(f"--cpu={args.target_cpu}")
468518

469-
if args.enable_mkl_dnn:
470-
logging.debug("Enabling MKL DNN")
471-
bazel_command.append("--config=mkl_open_source_only")
472-
473519
if hasattr(args, "disable_nccl") and args.disable_nccl:
474520
logging.debug("Disabling NCCL")
475521
bazel_command.append("--config=nonccl")
476522

477-
if args.enable_release_cpu_features:
478-
logging.debug(
479-
"Using release cpu features: --config=avx_%s",
480-
"windows" if os_name == "windows" else "posix",
481-
)
482-
if arch in ["x86_64", "AMD64"]:
483-
bazel_command.append(
484-
"--config=avx_windows"
485-
if os_name == "windows"
486-
else "--config=avx_posix"
487-
)
488-
489-
if args.enable_native_cpu_features:
490-
if os_name == "windows":
491-
logger.warning(
492-
"--target_cpu_features=native is not supported on Windows;"
493-
" ignoring."
494-
)
495-
else:
496-
logging.debug("Using native cpu features: --config=native_arch_posix")
497-
bazel_command.append("--config=native_arch_posix")
498-
499523
if "cuda" in args.command:
500524
if args.cuda_version:
501525
logging.debug("Hermetic CUDA version: %s", args.cuda_version)
@@ -513,54 +537,56 @@ async def main():
513537
args.cuda_compute_capabilities,
514538
)
515539
bazel_command.append(
516-
"--repo_env"
517-
f" HERMETIC_CUDA_COMPUTE_CAPABILITIES={args.cuda_compute_capabilities}"
540+
f"--repo_env=HERMETIC_CUDA_COMPUTE_CAPABILITIES={args.cuda_compute_capabilities}"
518541
)
519542

520543
if "rocm" in args.command:
521544
bazel_command.append("--config=rocm")
522545

523546
if args.rocm_path:
524547
logging.debug("ROCm tookit path: %s", args.rocm_path)
525-
bazel_command.append(f"--action_env ROCM_PATH='{args.rocm_path}'")
548+
bazel_command.append(f'--action_env=ROCM_PATH="{args.rocm_path}"')
526549
if args.rocm_amdgpu_targets:
527550
logging.debug("ROCm AMD GPU targets: %s", args.rocm_amdgpu_targets)
528551
bazel_command.append(
529-
f"--action_env TF_ROCM_AMDGPU_TARGETS={args.rocm_amdgpu_targets}"
552+
f"--action_env=TF_ROCM_AMDGPU_TARGETS={args.rocm_amdgpu_targets}"
530553
)
531554

532555
if args.local_xla_path:
533556
logging.debug("Local XLA path: %s", args.local_xla_path)
534-
bazel_command.append(f"--override_repository=xla={args.local_xla_path}")
557+
bazel_command.append(f'--override_repository=xla="{args.local_xla_path}"')
535558

536559
if args.bazel_build_options:
537560
logging.debug(
538561
"Additional Bazel build options: %s", args.bazel_build_options
539562
)
540-
parse_and_append_bazel_options(bazel_command, args.bazel_build_options)
563+
for option in args.bazel_build_options:
564+
bazel_command.append(option)
565+
566+
if not args.use_ci_bazelrc_flags:
567+
with open(".jax_configure.bazelrc", "w") as f:
568+
jax_configure_options = utils.get_jax_configure_bazel_options(bazel_command.command)
569+
f.write(jax_configure_options)
570+
logging.debug("Bazel options written to .jax_configure.bazelrc")
571+
if args.configure_only:
572+
logging.debug("--configure_only is set, exiting without running any Bazel commands.")
573+
sys.exit(0)
541574

542575
# Append the build target to the Bazel command.
543576
build_target = ARTIFACT_BUILD_TARGET_DICT[args.command]
544577
bazel_command.append(build_target)
545578

546-
# Read output directory. Default is store the artifacts in the "dist/"
547-
# directory in JAX's GitHub repository root.
548-
output_path = args.output_path
549-
550-
# If running on Windows, adjust the paths for compatibility.
551-
if os_name == "windows":
552-
output_path = utils.adjust_paths_for_windows(output_path)
579+
bazel_command.append("--")
553580

581+
output_path = args.output_path
554582
logger.debug("Artifacts output directory: %s", output_path)
555583

556-
bazel_command.append("--")
557-
558584
if args.editable:
559585
logger.debug("Building an editable build")
560586
output_path = os.path.join(output_path, args.command)
561587
bazel_command.append("--editable")
562588

563-
bazel_command.append(f"--output_path={output_path}")
589+
bazel_command.append(f'--output_path="{output_path}"')
564590
bazel_command.append(f"--cpu={target_cpu}")
565591

566592
if "cuda" in args.command:

build/tools/command.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
# ==============================================================================
15-
# Helper script for running subprocess commands.
15+
# Helper script for the JAX build CLI for running subprocess commands.
1616
import asyncio
1717
import dataclasses
1818
import datetime
@@ -27,7 +27,9 @@ def __init__(self, base_command: str):
2727
self.command = base_command
2828

2929
def append(self, parameter: str):
30-
self.command += " {}".format(parameter)
30+
# Use 2 spaces to easily distinguish the individual parameters. Useful
31+
# for systems like on Windows that can have a space in file paths.
32+
self.command += " {}".format(parameter)
3133
return self
3234

3335
@dataclasses.dataclass

0 commit comments

Comments
 (0)