204 lines
8.5 KiB
Diff
204 lines
8.5 KiB
Diff
Windows LLVM-MinGW build, portable helper assertions and optional diagnostic UI.
|
||
Apply after upstream d4r patches 0002 through 0007, on ZLUDA ee2f25a.
|
||
|
||
diff --git a/ext/highs-sys/build.rs b/ext/highs-sys/build.rs
|
||
--- a/ext/highs-sys/build.rs
|
||
+++ b/ext/highs-sys/build.rs
|
||
@@ -66,11 +66,12 @@
|
||
let linux = target.contains("linux");
|
||
let mingw = target.contains("pc-windows-gnu");
|
||
if apple {
|
||
println!("cargo:rustc-link-lib=dylib=c++");
|
||
} else if linux || mingw {
|
||
- println!("cargo:rustc-link-lib=dylib=stdc++");
|
||
+ let cxx_library = env::var("CXXSTDLIB").unwrap_or_else(|_| "stdc++".to_owned());
|
||
+ println!("cargo:rustc-link-lib=dylib={cxx_library}");
|
||
}
|
||
println!("cargo:rerun-if-changed=../HiGHS/highs/interfaces/highs_c_api.h");
|
||
|
||
true
|
||
}
|
||
diff --git a/ext/hip_runtime-sys/build.rs b/ext/hip_runtime-sys/build.rs
|
||
--- a/ext/hip_runtime-sys/build.rs
|
||
+++ b/ext/hip_runtime-sys/build.rs
|
||
@@ -1,8 +1,12 @@
|
||
fn main() {
|
||
if cfg!(windows) {
|
||
- println!("cargo:rustc-link-arg=/DELAYLOAD:amdhip64_7.dll");
|
||
+ if std::env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("gnu") {
|
||
+ println!("cargo:rustc-link-arg=-Wl,--delayload=amdhip64_7.dll");
|
||
+ } else {
|
||
+ println!("cargo:rustc-link-arg=/DELAYLOAD:amdhip64_7.dll");
|
||
+ }
|
||
} else {
|
||
println!("cargo:rustc-link-lib=dylib=amdhip64");
|
||
println!("cargo:rustc-link-search=native=/opt/rocm/lib/");
|
||
}
|
||
}
|
||
diff --git a/llvm_zluda/build.rs b/llvm_zluda/build.rs
|
||
--- a/llvm_zluda/build.rs
|
||
+++ b/llvm_zluda/build.rs
|
||
@@ -19,10 +19,18 @@
|
||
|
||
fn main() {
|
||
let bc_path1 = "src/device-libs/ockl.bc";
|
||
println!("cargo:rerun-if-changed={}", bc_path1);
|
||
check_lfs_file(bc_path1);
|
||
+
|
||
+ println!("cargo:rerun-if-env-changed=ZLUDA_LLVM_BUILD_DIR");
|
||
+ if let Some(directory) = env::var_os("ZLUDA_LLVM_BUILD_DIR") {
|
||
+ let llvm_build_path = PathBuf::from(directory);
|
||
+ println!("cargo:build-path={}", llvm_build_path.display());
|
||
+ link_prebuilt_llvm(&llvm_build_path);
|
||
+ return;
|
||
+ }
|
||
|
||
let mut cmake = Config::new(r"../ext/llvm-project/llvm");
|
||
try_use_sccache(&mut cmake);
|
||
try_use_ninja(&mut cmake);
|
||
cmake
|
||
@@ -57,16 +65,31 @@
|
||
cmake.build();
|
||
}
|
||
let cmake_profile = cmake.get_profile();
|
||
let llvm_build_path = get_llvm_build_path(&llvm_dir, cmake_profile);
|
||
println!("cargo:build-path={}", llvm_build_path.display());
|
||
+ link_prebuilt_llvm(&llvm_build_path);
|
||
+}
|
||
+
|
||
+fn link_prebuilt_llvm(llvm_build_path: &PathBuf) {
|
||
let (cxxflags, ldflags, libdir, lib_names, system_libs) =
|
||
llvm_config(&llvm_build_path.join("bin/llvm-config")).unwrap();
|
||
println!("cargo:rustc-link-arg={ldflags}");
|
||
println!("cargo:rustc-link-search=native={libdir}");
|
||
for lib in system_libs.split_ascii_whitespace() {
|
||
- println!("cargo:rustc-link-arg={lib}");
|
||
+ if let Some(name) = lib.strip_prefix("-l") {
|
||
+ println!("cargo:rustc-link-lib={name}");
|
||
+ } else {
|
||
+ println!("cargo:rustc-link-arg={lib}");
|
||
+ }
|
||
+ }
|
||
+ // llvm-config omits system libraries on Windows. Propagate these through
|
||
+ // this rlib to its final cdylib consumer (link-arg alone cannot do that).
|
||
+ if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") {
|
||
+ for library in ["psapi", "shell32", "ole32", "uuid", "advapi32", "ws2_32", "ntdll"] {
|
||
+ println!("cargo:rustc-link-lib={library}");
|
||
+ }
|
||
}
|
||
link_lld_components();
|
||
link_llvm_components(lib_names);
|
||
compile_cxx_lib(cxxflags, &llvm_build_path);
|
||
}
|
||
diff --git a/zluda/build.rs b/zluda/build.rs
|
||
--- a/zluda/build.rs
|
||
+++ b/zluda/build.rs
|
||
@@ -1,11 +1,15 @@
|
||
use vergen_gix::{Emitter, Gix};
|
||
|
||
fn main() {
|
||
if cfg!(windows) {
|
||
- println!("cargo:rustc-link-arg=delayimp.lib");
|
||
- println!("cargo:rustc-link-arg=/DELAYLOAD:amdhip64_7.dll");
|
||
+ if std::env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("gnu") {
|
||
+ println!("cargo:rustc-link-arg=-Wl,--delayload=amdhip64_7.dll");
|
||
+ } else {
|
||
+ println!("cargo:rustc-link-arg=delayimp.lib");
|
||
+ println!("cargo:rustc-link-arg=/DELAYLOAD:amdhip64_7.dll");
|
||
+ }
|
||
let dll_path = "bin/nvcudart_hybrid64.dll";
|
||
println!("cargo:rerun-if-changed={}", dll_path);
|
||
check_lfs_file(dll_path);
|
||
}
|
||
let git = Gix::builder().sha(false).build();
|
||
diff --git a/zluda_windows/src/lib.rs b/zluda_windows/src/lib.rs
|
||
--- a/zluda_windows/src/lib.rs
|
||
+++ b/zluda_windows/src/lib.rs
|
||
@@ -11,27 +11,27 @@
|
||
use uuid::uuid;
|
||
use widestring::{u16str, U16Str, U16String};
|
||
use windows::{
|
||
core::{w, HRESULT, PCWSTR},
|
||
Win32::{
|
||
- Foundation::{HANDLE, HINSTANCE, HMODULE, HWND, LPARAM, S_OK, WPARAM},
|
||
+ Foundation::{FreeLibrary, HANDLE, HINSTANCE, HMODULE, HWND, LPARAM, S_OK, WPARAM},
|
||
System::{
|
||
JobObjects::{
|
||
AssignProcessToJobObject, JobObjectExtendedLimitInformation,
|
||
SetInformationJobObject, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
|
||
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
|
||
},
|
||
LibraryLoader::{
|
||
- GetModuleFileNameA, GetModuleFileNameW, GetModuleHandleExW, LoadLibraryExW,
|
||
+ GetModuleFileNameA, GetModuleFileNameW, GetModuleHandleExW, GetProcAddress, LoadLibraryExW,
|
||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS,
|
||
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR,
|
||
+ LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32,
|
||
},
|
||
},
|
||
UI::{
|
||
Controls::{
|
||
- TaskDialogIndirect, TASKDIALOGCONFIG, TASKDIALOGCONFIG_0, TASKDIALOGCONFIG_1,
|
||
+ TASKDIALOGCONFIG, TASKDIALOGCONFIG_0, TASKDIALOGCONFIG_1,
|
||
TASKDIALOG_NOTIFICATIONS, TDCBF_CLOSE_BUTTON, TDF_ENABLE_HYPERLINKS,
|
||
TDN_HYPERLINK_CLICKED, TD_ERROR_ICON,
|
||
},
|
||
WindowsAndMessaging::IDCLOSE,
|
||
},
|
||
@@ -487,11 +487,23 @@
|
||
pszFooter: PCWSTR::null(),
|
||
pfCallback: Some(task_dialog_callback),
|
||
lpCallbackData: 0,
|
||
cxWidth: 0,
|
||
};
|
||
- TaskDialogIndirect(&config, None, None, None).ok();
|
||
+ // A CUDA DLL may be loaded by an executable with no Common Controls
|
||
+ // v6 activation manifest. Do not make its diagnostic UI an eager DLL
|
||
+ // import: comctl32 v5 has no TaskDialogIndirect export.
|
||
+ if let Ok(controls) = LoadLibraryExW(w!("comctl32.dll"), None, LOAD_LIBRARY_SEARCH_SYSTEM32) {
|
||
+ if let Some(raw) = GetProcAddress(controls, windows::core::s!("TaskDialogIndirect")) {
|
||
+ let show: unsafe extern "system" fn(*const TASKDIALOGCONFIG, *mut i32, *mut i32, *mut i32) -> HRESULT =
|
||
+ mem::transmute(raw);
|
||
+ let _ = show(&config, ptr::null_mut(), ptr::null_mut(), ptr::null_mut());
|
||
+ } else {
|
||
+ eprintln!("ZLUDA failed to load {}; set HIP_PATH to the selected HIP SDK", redirect_names[0]);
|
||
+ }
|
||
+ let _ = FreeLibrary(controls);
|
||
+ }
|
||
}
|
||
result
|
||
}
|
||
|
||
unsafe extern "system" fn task_dialog_callback(
|
||
diff --git a/ptx/lib/zluda_ptx_impl.cpp b/ptx/lib/zluda_ptx_impl.cpp
|
||
--- a/ptx/lib/zluda_ptx_impl.cpp
|
||
+++ b/ptx/lib/zluda_ptx_impl.cpp
|
||
@@ -405,11 +405,26 @@
|
||
uint32_t line,
|
||
uint64_t function,
|
||
uint64_t char_size)
|
||
{
|
||
(void)char_size;
|
||
+#if defined(_WIN32) || defined(_WIN64)
|
||
+ // HIP on Windows only supplies the wide _wassert entry point. Keep the
|
||
+ // CUDA assertion's ASCII diagnostics and trap through public OCKL APIs.
|
||
+ auto output = __ockl_fprintf_stderr_begin();
|
||
+ const char* parts[] = {"CUDA assertion: ", (const char*)message, " at ", (const char*)file,
|
||
+ " in ", (const char*)function, "\n"};
|
||
+ for (const char* part : parts) {
|
||
+ const char* end = part;
|
||
+ while (*end) ++end;
|
||
+ output = __ockl_fprintf_append_string_n(output, part, end - part, 0);
|
||
+ }
|
||
+ __ockl_fprintf_append_args(output, 1, line, 0, 0, 0, 0, 0, 0, 1);
|
||
+ __builtin_trap();
|
||
+#else
|
||
[[clang::noinline]] __assert_fail((const char *)message, (const char *)file, line, (const char *)function);
|
||
+#endif
|
||
}
|
||
|
||
// * Smallest denormal is 1.4 × 10^-45
|
||
// * Smallest normal is ~1.175494351 × 10^(-38)
|
||
// * Now, 1.175494351×10^-38 / 1.4 × 10^-45 = 8396388 + 31/140
|