Linux下MKL函数参数类型不兼容问题求助(Windows正常)
解决MKL跨平台编译时int与long long int类型不兼容问题
问题根源
你在Linux下链接的是MKL的ILP64接口(MKL::mkl_intel_ilp64),而Windows Visual Studio默认使用LP64接口:
- ILP64接口中,MKL的核心整数类型(矩阵维度、索引、步长等)为
long long(64位) - LP64接口中,这些整数类型为
int(32位)
两者的类型差异导致代码中传递int*参数时,在Linux下触发类型转换警告。
两种解决方案
方案一:切换至LP64接口(与Windows保持一致)
修改CMakeLists.txt中的链接目标,将ILP64库替换为LP64库,无需修改代码即可兼容:
#find MKL on Linux find_package(MKL REQUIRED) message(STATUS "${MKL_IMPORTED_TARGETS}") if(MKL_FOUND) message(STATUS "MKL IS FOUND ON LINUX") message(STATUS "MKL_ROOT IS ${MKL_ROOT}") include_directories(${MKL_ROOT}/include) # 将mkl_intel_ilp64替换为mkl_intel_lp64 target_link_libraries(algebra_test_linux PRIVATE MKL::mkl_intel_lp64 MKL::mkl_intel_thread MKL::mkl_core MKL::MKL) else() message(WARNING "MKL libs not found") endif(MKL_FOUND)
该方案适合不需要处理超过2^31-1维度矩阵的场景,快速实现跨平台兼容。
方案二:适配ILP64接口(支持大维度矩阵)
如果项目需要处理超大矩阵,可修改代码使用MKL统一的整数类型MKL_INT,确保跨平台类型一致:
修改后的测试代码示例:
#include "mkl_test_linux.h" #include<stdio.h> #include<stdlib.h> #include<mkl.h> int main() { float* A, * B; int a = 1, b = 1; MKL_INT n = 5; // 使用MKL定义的整数类型 A = (float*)mkl_malloc(n * 1 * sizeof(float), 64); B = (float*)mkl_malloc(n * 1 * sizeof(float), 64); printf("The 1st vector is "); for (MKL_INT i = 0; i < n; i++) { // 循环索引同步改为MKL_INT A[i] = i; printf("%2.0f", A[i]); } printf("\n"); printf("The 2nd vector is "); for (MKL_INT i = 0; i < n; i++) { B[i] = i + 1; printf("%2.0f", B[i]); } printf("\n"); // 调用MKL接口时,所有维度、步长参数都使用MKL_INT cblas_saxpby(n, a, A, (MKL_INT)1, b, B, (MKL_INT)1); printf("The a*A+b*B is "); for (MKL_INT i = 0; i < n; i++) { printf("%2.0f", B[i]); } printf("\n"); mkl_free(A); mkl_free(B); getchar(); return 0; }
CMakeLists.txt保持原ILP64链接配置即可,该方案能充分利用64位整数的寻址能力,支持更大规模的计算。
内容的提问来源于stack exchange,提问作者Chan
相关产品推荐
相关产品推荐

