I want to bench the cblas_dgemm function from MKL, BLIS, and OpenBLAS in the same exe file. All of them are dynamic link libraries installed on the system, and their cblas_dgemm function symbol are identical. So, I wrote a middle layer to distinguish them, but I found that the finally compiled executable cannot tell them apart and only uses the first linked library. How should I solve this problem?
#Using the same func symbol from different dynamic link libraries
1 messages · Page 1 of 1 (latest)
build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const bench_exe = b.addExecutable(.{
.name = "bench",
.root_module = b.createModule(.{
.root_source_file = b.path("src/bench.zig"),
.target = target,
.optimize = optimize,
.imports = &.{},
}),
});
const bench_mkl_lib = b.addLibrary(.{
.name = "bench_mkl",
.linkage = .dynamic,
.root_module = b.createModule(.{
.root_source_file = b.path("src/bench_mkl.zig"),
.target = target,
.optimize = optimize,
.imports = &.{},
}),
});
bench_mkl_lib.linkLibC();
bench_mkl_lib.addSystemIncludePath(.{ .cwd_relative = "/usr/include/mkl" });
bench_mkl_lib.linkSystemLibrary("mkl_intel_thread");
bench_mkl_lib.linkSystemLibrary("mkl_rt");
bench_mkl_lib.linkSystemLibrary("mkl_core");
bench_mkl_lib.linkSystemLibrary("mkl_intel_lp64");
b.installArtifact(bench_mkl_lib);
bench_exe.root_module.linkLibrary(bench_mkl_lib);
b.installArtifact(bench_exe);
const bench_step = b.step("bench", "bench");
const bench_cmd = b.addRunArtifact(bench_exe);
bench_step.dependOn(&bench_cmd.step);
bench_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
bench_cmd.addArgs(args);
}
}
const bench_openblas_lib = b.addLibrary(.{
.name = "bench_openblas",
.linkage = .dynamic,
.root_module = b.createModule(.{
.root_source_file = b.path("src/bench_openblas.zig"),
.target = target,
.optimize = optimize,
.imports = &.{},
}),
});
bench_openblas_lib.linkLibC();
bench_openblas_lib.linkSystemLibrary("openblas");
b.installArtifact(bench_openblas_lib);
bench_exe.root_module.linkLibrary(bench_openblas_lib);
const bench_blis_lib = b.addLibrary(.{
.name = "bench_blis",
.linkage = .dynamic,
.root_module = b.createModule(.{
.root_source_file = b.path("src/bench_blis.zig"),
.target = target,
.optimize = optimize,
.imports = &.{},
}),
});
bench_blis_lib.linkLibC();
bench_blis_lib.addSystemIncludePath(.{ .cwd_relative = "/usr/include/x86_64-linux-gnu/blis-openmp" });
bench_blis_lib.linkSystemLibrary("blis");
b.installArtifact(bench_blis_lib);
bench_exe.root_module.linkLibrary(bench_blis_lib);
bench_blis.zig
const std = @import("std");
const c = @cImport(@cInclude("cblas.h"));
export fn blis_dgemm(M: c_int, N: c_int, K: c_int, alpha: f64, A: [*c]const f64, lda: c_int, B: [*c]const f64, ldb: c_int, beta: f64, C: [*c]f64, ldc: c_int) void {
c.cblas_dgemm(c.CblasRowMajor, c.CblasNoTrans, c.CblasNoTrans, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
}
bench.zig
extern fn mkl_dgemm(M: c_int, N: c_int, K: c_int, alpha: f64, A: [*c]const f64, lda: c_int, B: [*c]const f64, ldb: c_int, beta: f64, C: [*c]f64, ldc: c_int) void;
extern fn blis_dgemm(M: c_int, N: c_int, K: c_int, alpha: f64, A: [*c]const f64, lda: c_int, B: [*c]const f64, ldb: c_int, beta: f64, C: [*c]f64, ldc: c_int) void;
extern fn openblas_dgemm(M: c_int, N: c_int, K: c_int, alpha: f64, A: [*c]const f64, lda: c_int, B: [*c]const f64, ldb: c_int, beta: f64, C: [*c]f64, ldc: c_int) void;
const std = @import("std");
pub fn main() !void {
// ...
}
you can extern "name" fn foo() void;
to get foo from the libname library
you should probably have a namespace for each library.
there is also const foo = @extern(T, .{ .name = "bar", .library_name = "baz});
@crystal thicket
I tried it, but it still doesn’t work—the executable only uses the first linked library.