Skip to content

Correctly identify BLAS as ILP64 on Darwin#172

Draft
Feyorsh wants to merge 1 commit intoJuliaLinearAlgebra:mainfrom
Feyorsh:ilp64-darwin
Draft

Correctly identify BLAS as ILP64 on Darwin#172
Feyorsh wants to merge 1 commit intoJuliaLinearAlgebra:mainfrom
Feyorsh:ilp64-darwin

Conversation

@Feyorsh
Copy link
Copy Markdown

@Feyorsh Feyorsh commented Apr 12, 2026

On Darwin, depending on how a BLAS library was built it may have access to a copy of libBLAS from Apple's Accelerate framework through the dyld shared cache.
This is problematic for autodetecting whether the loaded BLAS is LP64 or ILP64, because symbols from Accelerate will "pollute" the namespace of symbols that dlopen can probe for.

I think it might be easier to show an example:

const std = @import("std");
const c = @cImport({
    @cInclude("dlfcn.h");
});

pub fn main() !void {
    // or libgfortran, libquadmath, libintl, etc...
    const handle = std.c.dlopen("libopenblas64_.dylib", .{ .NOW = true, .LOCAL = true });
    const isamax_addr = std.c.dlsym(handle.?, "isamax_").?;
    const isamax: *fn (*i64, [*]f32, *i64) callconv(.C) i64 = @alignCast(@ptrCast(isamax_addr));

    const n: i64 = @bitCast(@as(u64, 0xffffffff00000003));
    const X = [3]f32{ 1.0, 2.0, 1.0 };
    const incx: i64 = 1;

    var max_idx = isamax(@constCast(&n), @constCast(@ptrCast(&X)), @constCast(&incx));
    max_idx &= 0xffffffff;

    std.debug.print("max_idx: {} (0 means ILP64, 2 means LP64)\n", .{max_idx});

    var info: c.Dl_info = undefined;
    _ = c.dladdr(isamax_addr, &info);
    std.debug.print("info: {s}\n", .{info.dli_fname});
}
max_idx: 2 (0 means ILP64, 2 means LP64)
info: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib

Notice how isamax_ appears to be defined in libopenblas64_.dylib when doing the dlopen check, but in reality it is defined in /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib.
(This version of libopenblas64_.dylib was built as part of the Nix derivation for Julia and it directly links to the version of BLAS packaged in nixpkgs.)

Note that while this issue appears to only be present on BLAS libraries from nixpkgs, I still believe this necessitates a fix in LBT.

Solution

I think the fix is simple, which is to try searching for ILP64 symbols first before the LP64 symbols (which will resolve, but they're not what we want). I suppose this could cause the opposite problem where someone's LP64 library is being misidentified as ILP64, but I'm not sure if that would ever happen in practice.

@Feyorsh Feyorsh marked this pull request as draft April 12, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant