distributed tests if distributed package is not available. if not dist.is_available(): selected_tests = exclude_tests( -@@ -2100,8 +2096,6 @@ def main(): - - - def main(): -- check_pip_packages() -- - options = parse_args() - tests_to_include_env = os.environ.get("TESTS_TO_INCLUDE", "").strip() - if tests_to_include_env: +@@ -2086,7 +2121,7 @@ def check_pip_packages() -> None: + def check_pip_packages() -> None: + packages = [ + "pytest-rerunfailures", +- "pytest-flakefinder", ++ # pytest-flakefinder is not available as a FreeBSD port; skip check + "pytest-xdist", + ] + try: diff --git a/misc/py-pytorch/files/patch-test_test__cpp__extensions__jit.py b/misc/py-pytorch/files/patch-test_test__cpp__extensions__jit.py new file mode 100644 index 000000000000..0f93187d98b1 --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__cpp__extensions__jit.py @@ -0,0 +1,12 @@ +--- test/test_cpp_extensions_jit.py.orig 2026-04-18 16:52:06 UTC ++++ test/test_cpp_extensions_jit.py +@@ -733,7 +733,8 @@ class TestCppExtensionJIT(common.TestCase): + self.assertEqual(module.f(), 789) + + @unittest.skipIf( +- "utf" not in locale.getlocale()[1].lower(), "Only test in UTF-8 locale" ++ not (locale.getlocale()[1] and "utf" in locale.getlocale()[1].lower()), ++ "Only test in UTF-8 locale", + ) + def test_load_with_non_platform_default_encoding(self): + # Assume the code is saved in UTF-8, but the locale is set to a different encoding. diff --git a/misc/py-pytorch/files/patch-test_test__fx.py b/misc/py-pytorch/files/patch-test_test__fx.py new file mode 100644 index 000000000000..dc6c33660421 --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__fx.py @@ -0,0 +1,43 @@ +--- test/test_fx.py.orig 2026-04-18 17:21:07 UTC ++++ test/test_fx.py +@@ -248,9 +248,12 @@ class TestFX(JitTestCase): + ) + torch.fx.proxy.TracerBase.check_mutable_operations = True + ++ self._torchbind_test_loaded = False + if not (IS_FBCODE or IS_WINDOWS or IS_MACOS): + lib_file_path = find_library_location("libtorchbind_test.so") +- torch.ops.load_library(str(lib_file_path)) ++ if lib_file_path.exists(): ++ torch.ops.load_library(str(lib_file_path)) ++ self._torchbind_test_loaded = True + + def tearDown(self): + super().tearDown() +@@ -869,7 +872,7 @@ class TestFX(JitTestCase): + self.checkGraphModule(m, (a, b)) + + def test_native_callable(self): +- if IS_FBCODE or IS_WINDOWS or IS_MACOS: ++ if IS_FBCODE or IS_WINDOWS or IS_MACOS or not self._torchbind_test_loaded: + raise unittest.SkipTest("non-portable load_library call used in test") + # This test exercises the case where we use FX to translate from Python + # code to some native callable object +@@ -3062,7 +3065,7 @@ class TestFX(JitTestCase): + node.__update_args_kwargs((), {}) + + def test_torchbind_class_attribute_in_fx(self): +- if IS_FBCODE or IS_WINDOWS or IS_MACOS: ++ if IS_FBCODE or IS_WINDOWS or IS_MACOS or not self._torchbind_test_loaded: + self.skipTest( + "torch.classes._TorchScriptTesting._StackString is registered, skipping" + ) +@@ -3079,7 +3082,7 @@ class TestFX(JitTestCase): + self.checkGraphModule(m, ()) + + def test_torchbind_class_attribute_in_fx_tensor_arg(self): +- if IS_FBCODE or IS_WINDOWS or IS_MACOS: ++ if IS_FBCODE or IS_WINDOWS or IS_MACOS or not self._torchbind_test_loaded: + self.skipTest( + "torch.classes._TorchScriptTesting._ReLUClass is registered, skipping" + ) diff --git a/misc/py-pytorch/files/patch-test_test__jit.py b/misc/py-pytorch/files/patch-test_test__jit.py new file mode 100644 index 000000000000..ccb3b8585f70 --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__jit.py @@ -0,0 +1,35 @@ +--- test/test_jit.py.orig 2026-04-18 22:16:10 UTC ++++ test/test_jit.py +@@ -375,6 +375,10 @@ class TestJitProfiler(JitTestCase): + self.graph_executor_optimize_opt + ) + ++ @unittest.skipIf( ++ sys.platform.startswith("freebsd"), ++ "Hangs on FreeBSD due to profiler/JIT interaction deadlock", ++ ) + def test_profiler(self): + torch._C._set_graph_executor_optimize(False) + +@@ -1832,6 +1836,10 @@ graph(%Ra, %Rb): + + @slowTest + @unittest.skipIf(GRAPH_EXECUTOR != ProfilingMode.LEGACY, 'Testing differentiable graph') ++ @unittest.skipIf( ++ GRAPH_EXECUTOR == ProfilingMode.LEGACY, ++ "Hangs in legacy executor mode due to profiler/JIT interaction", ++ ) + def test_dropout_module_requires_grad(self): + with enable_profiling_mode_for_profiling_tests(): + class MyModule(torch.nn.Module): +@@ -1875,6 +1883,10 @@ graph(%Ra, %Rb): + + @unittest.skipIf(GRAPH_EXECUTOR == ProfilingMode.SIMPLE, 'Testing differentiable graph') + @skipIfTorchDynamo("Torchdynamo cannot correctly handle profiler.profile calls") ++ @unittest.skipIf( ++ sys.platform.startswith("freebsd"), ++ "Hangs on FreeBSD due to profiler/JIT interaction deadlock", ++ ) + def test_dropout_func_requires_grad(self): + def dropout_training(input): + return F.dropout(input, 0.5, training=True) diff --git a/misc/py-pytorch/files/patch-test_test__jit__profiling.py b/misc/py-pytorch/files/patch-test_test__jit__profiling.py new file mode 100644 index 000000000000..1bd0d3e409ee --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__jit__profiling.py @@ -0,0 +1,16 @@ +--- test/test_jit_profiling.py.orig 2026-04-18 23:58:15 UTC ++++ test/test_jit_profiling.py +@@ -2,6 +2,13 @@ sys.argv.append("--jit-executor=profiling") + + import sys + sys.argv.append("--jit-executor=profiling") ++from torch.testing._internal.common_utils import parse_cmd_line_args, run_tests # noqa: F401 ++ ++if __name__ == '__main__': ++ # The value of GRAPH_EXECUTOR depends on command line arguments so make sure they're parsed ++ # before instantiating tests. ++ parse_cmd_line_args() ++ + from test_jit import * # noqa: F403 + + if __name__ == '__main__': diff --git a/misc/py-pytorch/files/patch-test_test__multiprocessing.py b/misc/py-pytorch/files/patch-test_test__multiprocessing.py new file mode 100644 index 000000000000..03b205149cbc --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__multiprocessing.py @@ -0,0 +1,21 @@ +--- test/test_multiprocessing.py.orig 2026-04-19 00:27:38 UTC ++++ test/test_multiprocessing.py +@@ -33,7 +33,7 @@ TEST_REPEATS = 30 + load_tests = load_tests # noqa: PLW0127 + + TEST_REPEATS = 30 +-HAS_SHM_FILES = os.path.isdir("/dev/shm") ++HAS_SHM_FILES = os.path.isdir("/dev/shm") and not sys.platform.startswith("freebsd") + MAX_WAITING_TIME_IN_SECONDS = 30 + + TEST_CUDA_IPC = ( +@@ -497,7 +497,8 @@ class TestMultiprocessing(TestCase): + simple_autograd_function() + # Autograd only uses thread when GPUs are involved + if ( +- torch.cuda.is_available() ++ sys.platform.startswith("freebsd") ++ or torch.cuda.is_available() + or torch.backends.mps.is_available() + or torch.xpu.is_available() + ): diff --git a/misc/py-pytorch/files/patch-test_test__torch.py b/misc/py-pytorch/files/patch-test_test__torch.py new file mode 100644 index 000000000000..208fbbcbe079 --- /dev/null +++ b/misc/py-pytorch/files/patch-test_test__torch.py @@ -0,0 +1,12 @@ +--- test/test_torch.py.orig 2026-04-19 01:42:54 UTC ++++ test/test_torch.py +@@ -9464,7 +9464,8 @@ tensor([[[1.+1.j, 1.+1.j, 1.+1.j, ..., 1.+1.j, 1.+1.j + torch.backends.quantized.engine = qe + if torch.backends.quantized.engine != qe: + raise AssertionError(f"qengine not set successfully: expected {qe}, got {torch.backends.quantized.engine}") +- torch.backends.quantized.engine = original_qe ++ if original_qe in qengines: ++ torch.backends.quantized.engine = original_qe + + def test_terminate_handler_on_crash(self): + cmd = [sys.executable, '-c', "import os; os.environ[\"TORCH_CUSTOM_TERMINATE\"] ='1'; \ diff --git a/misc/py-pytorch/files/patch-torch___inductor_compile__worker_____main____.py b/misc/py-pytorch/files/patch-torch___inductor_compile__worker_____main____.py new file mode 100644 index 000000000000..115e1cf1fd23 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_compile__worker_____main____.py @@ -0,0 +1,11 @@ +--- torch/_inductor/compile_worker/__main__.py.orig 2026-04-19 02:49:11 UTC ++++ torch/_inductor/compile_worker/__main__.py +@@ -30,7 +30,7 @@ try: + import triton + + assert triton is not None # preload in parent +-except ImportError: ++except (ImportError, AttributeError): + pass + + diff --git a/misc/py-pytorch/files/patch-torch___inductor_cpp__builder.py b/misc/py-pytorch/files/patch-torch___inductor_cpp__builder.py new file mode 100644 index 000000000000..7ac2d5428b6b --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_cpp__builder.py @@ -0,0 +1,13 @@ +--- torch/_inductor/cpp_builder.py.orig 2026-04-18 06:34:35 UTC ++++ torch/_inductor/cpp_builder.py +@@ -1185,6 +1185,10 @@ def _get_torch_related_args( + if _IS_WINDOWS: + libraries.append("sleef") + ++ if sys.platform.startswith("freebsd"): ++ include_dirs.append("/usr/local/include") ++ libraries.append("sleef") ++ + return include_dirs, libraries_dirs, libraries + + diff --git a/misc/py-pytorch/files/patch-torch___inductor_cpu__vec__isa.py b/misc/py-pytorch/files/patch-torch___inductor_cpu__vec__isa.py new file mode 100644 index 000000000000..df68e32921ee --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_cpu__vec__isa.py @@ -0,0 +1,31 @@ +--- torch/_inductor/cpu_vec_isa.py.orig 2026-04-18 06:29:09 UTC ++++ torch/_inductor/cpu_vec_isa.py +@@ -438,7 +438,7 @@ def x86_isa_checker() -> list[str]: + """ + Arch value is x86_64 on Linux, and the value is AMD64 on Windows. + """ +- if Arch != "x86_64" and Arch != "AMD64": ++ if Arch != "x86_64" and Arch != "AMD64" and Arch != "amd64": + return supported_isa + + avx2 = torch.cpu._is_avx2_supported() +@@ -504,7 +504,9 @@ def valid_vec_isa_list() -> list[VecISA]: + if sys.platform == "darwin" and platform.processor() == "arm": + isa_list.append(VecNEON()) + +- if sys.platform not in ["linux", "win32"]: ++ if sys.platform not in ["linux", "win32"] and not sys.platform.startswith( ++ "freebsd" ++ ): + return isa_list + + arch = platform.machine() +@@ -529,7 +531,7 @@ def valid_vec_isa_list() -> list[VecISA]: + else: + isa_list.append(VecNEON()) + +- elif arch in ["x86_64", "AMD64"]: ++ elif arch in ["x86_64", "AMD64", "amd64"]: + """ + arch value is x86_64 on Linux, and the value is AMD64 on Windows. + """ diff --git a/misc/py-pytorch/files/patch-torch___inductor_ir.py b/misc/py-pytorch/files/patch-torch___inductor_ir.py new file mode 100644 index 000000000000..f92c7880bb61 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_ir.py @@ -0,0 +1,11 @@ +--- torch/_inductor/ir.py.orig 2026-04-19 02:49:11 UTC ++++ torch/_inductor/ir.py +@@ -133,7 +133,7 @@ try: + + triton_version = triton.__version__ + has_triton = True +-except ImportError: ++except (ImportError, AttributeError): + triton_version = None + has_triton = False + diff --git a/misc/py-pytorch/files/patch-torch___inductor_kernel_mm.py b/misc/py-pytorch/files/patch-torch___inductor_kernel_mm.py new file mode 100644 index 000000000000..bb49e34c8678 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_kernel_mm.py @@ -0,0 +1,11 @@ +--- torch/_inductor/kernel/mm.py.orig 2026-04-19 02:49:11 UTC ++++ torch/_inductor/kernel/mm.py +@@ -70,7 +70,7 @@ try: + + triton_version = TorchVersion(triton.__version__) + has_triton = True +-except ImportError: ++except (ImportError, AttributeError): + triton_version = TorchVersion("0.0.0") + has_triton = False + diff --git a/misc/py-pytorch/files/patch-torch___inductor_runtime_triton__compat.py b/misc/py-pytorch/files/patch-torch___inductor_runtime_triton__compat.py new file mode 100644 index 000000000000..3d2d9a445daa --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___inductor_runtime_triton__compat.py @@ -0,0 +1,12 @@ +--- torch/_inductor/runtime/triton_compat.py.orig 2026-04-19 02:47:11 UTC ++++ torch/_inductor/runtime/triton_compat.py +@@ -8,7 +8,8 @@ try: + + try: + import triton +-except ImportError: ++ import triton.language # Verify it's a real install, not a namespace package ++except (ImportError, AttributeError): + triton = None + + diff --git a/misc/py-pytorch/files/patch-torch___utils__internal.py b/misc/py-pytorch/files/patch-torch___utils__internal.py new file mode 100644 index 000000000000..66f6922f397e --- /dev/null +++ b/misc/py-pytorch/files/patch-torch___utils__internal.py @@ -0,0 +1,14 @@ +--- torch/_utils_internal.py.orig 2026-04-18 15:44:50 UTC ++++ torch/_utils_internal.py +@@ -265,7 +265,10 @@ USE_GLOBAL_DEPS = True + USE_GLOBAL_DEPS = True + # USE_RTLD_GLOBAL_WITH_LIBTORCH controls whether __init__.py tries to load + # _C.so with RTLD_GLOBAL during the call to dlopen. +-USE_RTLD_GLOBAL_WITH_LIBTORCH = False ++# On FreeBSD, we need RTLD_GLOBAL to ensure weak RTTI typeinfo symbols (e.g. ++# c10::TypeError) are shared across DSO boundaries, enabling correct C++ ++# exception translation in JIT-compiled extensions. ++USE_RTLD_GLOBAL_WITH_LIBTORCH = sys.platform.startswith("freebsd") + # If an op was defined in C++ and extended from Python using the + # torch.library.register_fake, returns if we require that there be a + # m.set_python_module("mylib.ops") call from C++ that associates diff --git a/misc/py-pytorch/files/patch-torch_csrc_Exceptions.cpp b/misc/py-pytorch/files/patch-torch_csrc_Exceptions.cpp new file mode 100644 index 000000000000..7f30185538ea --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_csrc_Exceptions.cpp @@ -0,0 +1,34 @@ +--- torch/csrc/Exceptions.cpp.orig 2026-04-18 16:00:24 UTC ++++ torch/csrc/Exceptions.cpp +@@ -11,6 +11,31 @@ + + #include + ++// Out-of-line definitions for python_error, PyTorchError, TypeError, AttributeError. ++// These establish key functions so that vtables/typeinfo are emitted only here ++// (in libtorch_python.so) and exported with default visibility, enabling ++// correct cross-DSO RTTI matching on FreeBSD and other ELF platforms. ++python_error::~python_error() { ++ if (type || value || traceback) { ++ pybind11::gil_scoped_acquire gil; ++ Py_XDECREF(type); ++ Py_XDECREF(value); ++ Py_XDECREF(traceback); ++ } ++} ++const char* python_error::what() const noexcept { ++ return message.c_str(); ++} ++const char* torch::PyTorchError::what() const noexcept { ++ return msg.c_str(); ++} ++PyObject* torch::TypeError::python_type() { ++ return PyExc_TypeError; ++} ++PyObject* torch::AttributeError::python_type() { ++ return PyExc_AttributeError; ++} ++ + PyObject *THPException_FatalError, *THPException_LinAlgError, + *THPException_OutOfMemoryError, *THPException_DistError, + *THPException_DistBackendError, *THPException_DistNetworkError, diff --git a/misc/py-pytorch/files/patch-torch_csrc_Exceptions.h b/misc/py-pytorch/files/patch-torch_csrc_Exceptions.h new file mode 100644 index 000000000000..3b6601ffdbfc --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_csrc_Exceptions.h @@ -0,0 +1,86 @@ +--- torch/csrc/Exceptions.h.orig 2026-04-18 16:00:24 UTC ++++ torch/csrc/Exceptions.h +@@ -153,7 +153,10 @@ extern PyObject *THPException_FatalError, *THPExceptio + + // Throwing this exception means that the python error flags have been already + // set and control should be immediately returned to the interpreter. +-struct python_error : public std::exception { ++// TORCH_PYTHON_API on the struct gives vtable/typeinfo default visibility so ++// they are exported from libtorch_python.so and can be matched across DSOs ++// (critical for FreeBSD libcxxrt which uses pointer-only RTTI comparison). ++struct TORCH_PYTHON_API python_error : public std::exception { + python_error() = default; + + python_error(const python_error& other) +@@ -181,18 +184,12 @@ struct python_error : public std::exception { + python_error& operator=(python_error&& other) = delete; + + // NOLINTNEXTLINE(bugprone-exception-escape) +- ~python_error() override { +- if (type || value || traceback) { +- pybind11::gil_scoped_acquire gil; +- Py_XDECREF(type); +- Py_XDECREF(value); +- Py_XDECREF(traceback); +- } +- } ++ // Non-inline: establishes key function so typeinfo is emitted only in ++ // Exceptions.cpp (with default visibility), enabling cross-DSO RTTI. ++ ~python_error() override; + +- const char* what() const noexcept override { +- return message.c_str(); +- } ++ // Non-inline for the same reason as ~python_error(). ++ const char* what() const noexcept override; + + void build_message() { + // Ensure we have the GIL. +@@ -274,34 +271,31 @@ TORCH_PYTHON_API std::string processErrorMsg(std::stri + + TORCH_PYTHON_API std::string processErrorMsg(std::string str); + +-// Abstract base class for exceptions which translate to specific Python types +-struct PyTorchError : public std::exception { ++// Abstract base class for exceptions which translate to specific Python types. ++// TORCH_PYTHON_API on the struct gives vtable/typeinfo default visibility so ++// they are exported from libtorch_python.so and can be matched across DSOs. ++struct TORCH_PYTHON_API PyTorchError : public std::exception { + PyTorchError() = default; + PyTorchError(std::string msg_) : msg(std::move(msg_)) {} + virtual PyObject* python_type() = 0; +- const char* what() const noexcept override { +- return msg.c_str(); +- } ++ // Defined out-of-line to establish a key function. ++ const char* what() const noexcept override; + std::string msg; + }; + + // Translates to Python TypeError +-struct TypeError : public PyTorchError { +- TORCH_PYTHON_API TypeError() = default; +- TORCH_PYTHON_API TypeError(std::string msg_) +- : PyTorchError(std::move(msg_)) {} ++struct TORCH_PYTHON_API TypeError : public PyTorchError { ++ TypeError() = default; ++ TypeError(std::string msg_) : PyTorchError(std::move(msg_)) {} + using PyTorchError::PyTorchError; +- PyObject* python_type() override { +- return PyExc_TypeError; +- } ++ // Out-of-line to give TypeError its own key function for RTTI export. ++ PyObject* python_type() override; + }; + + // Translates to Python AttributeError +-struct AttributeError : public PyTorchError { ++struct TORCH_PYTHON_API AttributeError : public PyTorchError { + using PyTorchError::PyTorchError; +- PyObject* python_type() override { +- return PyExc_AttributeError; +- } ++ PyObject* python_type() override; + }; + + // ATen warning handler for Python diff --git a/misc/py-pytorch/files/patch-torch_csrc_jit_ir_attributes.h b/misc/py-pytorch/files/patch-torch_csrc_jit_ir_attributes.h new file mode 100644 index 000000000000..26563e9add33 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_csrc_jit_ir_attributes.h @@ -0,0 +1,36 @@ +--- torch/csrc/jit/ir/attributes.h.orig 2026-04-18 20:22:08 UTC ++++ torch/csrc/jit/ir/attributes.h +@@ -66,6 +66,9 @@ struct ScalarAttributeValue : public AttributeValue { + struct ScalarAttributeValue : public AttributeValue { + using ConstructorType = T; + using ValueType = T; ++ // kAttrKind lets getAttr verify the runtime kind without dynamic_cast, ++ // working around FreeBSD libcxxrt pointer-based RTTI across DSO boundaries. ++ static constexpr AttributeKind kAttrKind = Kind; + ScalarAttributeValue(Symbol name, ConstructorType value_) + : AttributeValue(name), value_(std::move(value_)) {} + ValueType& value() { +@@ -86,6 +89,7 @@ struct VectorAttributeValue : public AttributeValue { + struct VectorAttributeValue : public AttributeValue { + using ConstructorType = std::vector; + using ValueType = std::vector; ++ static constexpr AttributeKind kAttrKind = Kind; + VectorAttributeValue(Symbol name, ConstructorType value_) + : AttributeValue(name), value_(std::move(value_)) {} + ValueType& value() { +@@ -126,6 +130,7 @@ struct TORCH_API GraphAttr : public AttributeValue { + struct TORCH_API GraphAttr : public AttributeValue { + using ConstructorType = std::shared_ptr; + using ValueType = std::shared_ptr; ++ static constexpr AttributeKind kAttrKind = AttributeKind::g; + GraphAttr(Symbol name, ConstructorType value_) + : AttributeValue(name), value_(std::move(value_)) {} + ValueType& value() { +@@ -143,6 +148,7 @@ struct TORCH_API GraphsAttr : public AttributeValue { + struct TORCH_API GraphsAttr : public AttributeValue { + using ConstructorType = std::vector>; + using ValueType = std::vector>; ++ static constexpr AttributeKind kAttrKind = AttributeKind::gs; + GraphsAttr(Symbol name, ConstructorType value_) + : AttributeValue(name), value_(std::move(value_)) {} + ValueType& value() { diff --git a/misc/py-pytorch/files/patch-torch_csrc_jit_ir_ir.h b/misc/py-pytorch/files/patch-torch_csrc_jit_ir_ir.h new file mode 100644 index 000000000000..624e3c52dbc2 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_csrc_jit_ir_ir.h @@ -0,0 +1,26 @@ +--- torch/csrc/jit/ir/ir.h.orig 2026-04-18 03:53:37 UTC ++++ torch/csrc/jit/ir/ir.h +@@ -943,11 +943,22 @@ struct TORCH_API Node { + typename T::ValueType& getAttr(Symbol name) const { + AT_ASSERT(name.is_attr()); + auto it = findAttr(name, true); +- auto* child = dynamic_cast(it->get()); ++ auto* base = it->get(); ++#if defined(__FreeBSD__) ++ // FreeBSD's libcxxrt uses pointer-based typeinfo comparison; dynamic_cast ++ // across DSO boundaries fails for template specialisations whose typeinfo ++ // symbol is HIDDEN (not exported). Use kind() + static_cast instead. ++ if (base->kind() != T::kAttrKind) { ++ throw IRAttributeError(name, true); ++ } ++ return static_cast(base)->value(); ++#else ++ auto* child = dynamic_cast(base); + if (child == nullptr) { + throw IRAttributeError(name, true); + } + return child->value(); ++#endif + } + using AVPtr = AttributeValue::Ptr; + // NB: For determinism, we use a vector rather than a hash map. This does diff --git a/misc/py-pytorch/files/patch-torch_csrc_jit_passes_inplace__check.cpp b/misc/py-pytorch/files/patch-torch_csrc_jit_passes_inplace__check.cpp new file mode 100644 index 000000000000..cd2b0094b85d --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_csrc_jit_passes_inplace__check.cpp @@ -0,0 +1,21 @@ +--- torch/csrc/jit/passes/inplace_check.cpp.orig 2026-04-18 04:20:00 UTC ++++ torch/csrc/jit/passes/inplace_check.cpp +@@ -7,8 +7,17 @@ static void CheckInplace(Block* block) { + static void CheckInplace(Block* block) { + for (auto node : block->nodes()) { + if (node->kind() == prim::PythonOp && node->hasAttribute(attr::inplace)) { ++ // On FreeBSD, ScalarAttributeValue typeinfo symbols are local to each ++ // DSO (no exported key function), so dynamic_cast across DSO boundaries ++ // (from python to cpu library) may fail. Guard with try/catch. ++ bool is_inplace = false; ++ try { ++ is_inplace = (bool)node->i(attr::inplace); ++ } catch (const std::exception&) { ++ // Cannot determine; treat as not-inplace (conservative safe default). ++ } + TORCH_CHECK( +- !node->i(attr::inplace), ++ !is_inplace, + "inplace ", + static_cast(node)->name(), + " not supported in the JIT"); diff --git a/misc/py-pytorch/files/patch-torch_distributed_elastic_multiprocessing_redirects.py b/misc/py-pytorch/files/patch-torch_distributed_elastic_multiprocessing_redirects.py new file mode 100644 index 000000000000..7982c51cfd73 --- /dev/null +++ b/misc/py-pytorch/files/patch-torch_distributed_elastic_multiprocessing_redirects.py @@ -0,0 +1,13 @@ +--- torch/distributed/elastic/multiprocessing/redirects.py.orig 2026-04-19 02:32:30 UTC ++++ torch/distributed/elastic/multiprocessing/redirects.py +@@ -31,7 +31,9 @@ def get_libc(): + ) + return None + else: +- return ctypes.CDLL("libc.so.6") ++ import ctypes.util ++ libc_name = ctypes.util.find_library("c") or "libc.so.6" ++ return ctypes.CDLL(libc_name) + + + libc = get_libc() diff --git a/misc/py-pytorch/files/patch-torch_jit___trace.py b/misc/py-pytorch/files/patch-torch_jit___trace.py index 5415c1466564..a34e198af2a1 100644 --- a/misc/py-pytorch/files/patch-torch_jit___trace.py +++ b/misc/py-pytorch/files/patch-torch_jit___trace.py @@ -1,6 +1,59 @@ --- torch/jit/_trace.py.orig 2026-04-18 00:49:58 UTC +++ torch/jit/_trace.py -@@ -445,8 +445,11 @@ def _check_trace( +@@ -300,6 +300,13 @@ def indent(s): + return "\n".join(["\t" + line for line in s.splitlines()]) + + ++def _safe_str(x): ++ try: ++ return str(x) ++ except RuntimeError: ++ return "" ++ ++ + class TracingCheckError(Exception): + def __init__(self, graph_diff_error, tensor_compare_error, extra_msg=None): + self.message = "Tracing failed sanity checks!\n" +@@ -387,12 +394,18 @@ def _check_trace( + mod_canonicalized = torch._C._jit_pass_canonicalize(traced_func.graph) + torch._C._jit_pass_inline(mod_canonicalized) + torch._C._jit_pass_erase_shape_information(mod_canonicalized) +- mod_str = str(mod_canonicalized) ++ try: ++ mod_str = str(mod_canonicalized) ++ except RuntimeError: ++ mod_str = "" + mod_str = re.sub(r"___torch_mangle_[0-9]+\.", "", mod_str) + check_canonicalized = torch._C._jit_pass_canonicalize(check_mod_func.graph) + torch._C._jit_pass_inline(check_canonicalized) + torch._C._jit_pass_erase_shape_information(check_canonicalized) +- check_str = str(check_canonicalized) ++ try: ++ check_str = str(check_canonicalized) ++ except RuntimeError: ++ check_str = "" + check_str = re.sub(r"___torch_mangle_[0-9]+\.", "", check_str) + + graph_diff_errors = None +@@ -407,10 +420,15 @@ def _check_trace( + for n_mod, n_check in zip( + mod_canonicalized.nodes(), check_canonicalized.nodes() + ): +- if str(n_mod) != str(n_check): ++ try: ++ n_mod_str = str(n_mod) ++ n_check_str = str(n_check) ++ except RuntimeError: *** 109 LINES SKIPPED ***