OpenCL 代码的 malloc 问题 - OS X 上 mach_vm_map 的巨大大小
malloc issue with a OpenCL code - Huge size of mach_vm_map on OS X
我有一个关于将 OpenCL 代码从 Linux(它工作的地方)移植到 Mac OS X 10.9.5.
的问题
在我使用 malloc 的代码部分,当我启动可执行文件时,出现以下错误:
OpenCLSimu(13400,0x7fff7da7c310) malloc: *** mach_vm_map(size=1556840295209897984) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
可以看到,申请的内存很大:1556840295209897984字节,所以分配失败。
这是分配部分的例程(在我的例子中 NumBodies 是 30720):
int OpenCLSimu::setup()
{
// Make sure numParticles is multiple of group size
numBodies = (cl_int)(((size_t) getNumParticles()
< groupSize) ? groupSize : getNumParticles());
initPos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(initPos, "Failed to allocate host memory. (initPos)");
initVel = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(initVel, "Failed to allocate host memory. (initVel)");
pos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(pos, "Failed to allocate host memory. (pos)");
vel= (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(vel, "Failed to allocate host memory. (vel)");
return NBODY_SUCCESS;
}
我不知道是否存在关系,但我在 https://bugs.openjdk.java.net/browse/JDK-8043507(使用 Java 语言)上发现在 OS X 上,我们必须指定 uint32_t 输入尺寸。
可能这个问题来自于我用于编译的clang编译器。
CC = /usr/bin/clang
CXX = /usr/bin/clang++
DEFINES = -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS = -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.9 -Wall -W $(DEFINES)
CXXFLAGS = -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.9 -Wall -W $(DEFINES)
我还尝试将 numBodies 设置为 3072 以查看 mach_vm_map
的巨大尺寸,我得到:
malloc: * mach_vm_map(size=868306322687266816) 失败(错误代码=3)
* 错误:无法分配区域
*** 在 malloc_error_break 中设置断点以调试
我注意到这些尺寸总是随着不同的执行而变化。
最后,我将 pos
和 vel
数组的 Linux 版本放入上述例程中:
pos = (cl_double*)memalign(16, numBodies * sizeof(cl_double4));
vel = (cl_double*)memalign(16, numBodies * sizeof(cl_double4));
而不是 malloc 使用:
pos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
vel= (cl_double*) malloc(numBodies * sizeof(cl_double4));
我看到在 OS X 上,数据默认在 16 字节边界对齐,这就是为什么我将 memalign
替换为 malloc
以代替 MacOS版本
如果有人有线索,那就太好了。
提前致谢。
更新:
错误发生在“cout << size of source =" << sourceSize << endl
”和“cout << "status =" << status << endl
”之间,因此在clCreateProgramWithSource
方法上失败:
// create a CL program using the kernel source
const char *kernelName = "Simu_Kernels.cl";
FILE *fp = fopen(kernelName, "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
char *source = (char*)malloc(10000);
int sourceSize = fread( source, 1, 10000, fp);
fclose(fp);
cout << "size of source =" << sourceSize << endl;
// Create a program from the kernel source
program = clCreateProgramWithSource(context, 1, (const char **)&source, (const size_t *)&sourceSize, &status);
//program = clCreateProgramWithSource(context, 1, (const char **)&source, NULL, &status);
cout << "status =" << status << endl;
cout << "current_device =" << current_device<< endl;
在执行时,我得到:
Selected Platform Vendor : Apple
Device 0 : Iris Pro Device ID is 0x1024500
Device 1 : GeForce GT 750M Device ID is 0x1022700
size of source =2026
OpenCLSimu(15802,0x7fff7da7c310) malloc: *** mach_vm_map(size=59606861803950080) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
status =-6
和status = -6
对应一个CL_OUT_OF_HOST_MEMORY
我让你注意到我的 macbook 上有 2 个 GPU 单元(Iris Pro Device 和 GeForce GT 750M)。我对两个设备都有同样的错误。
尝试创建程序如下:
static char* Read_Source_File(
const char *filename,
size_t *file_len)
{
long int
size = 0,
res = 0;
char *src = NULL;
FILE *file = fopen(filename, "rb");
if (!file) return NULL;
if (fseek(file, 0, SEEK_END))
{
fclose(file);
return NULL;
}
size = ftell(file);
*file_len = size;
if (size == 0)
{
fclose(file);
return NULL;
}
rewind(file);
src = (char *)calloc(size + 1, sizeof(char));
if (!src)
{
src = NULL;
fclose(file);
return src;
}
res = fread(src, 1, sizeof(char) * size, file);
if (res != sizeof(char) * size)
{
fclose(file);
free(src);
return (char*)NULL;
}
src[size] = '[=10=]'; /* NULL terminated */
fclose(file);
return src;
}
size_t file_len;
char *source = Read_Source_File("path_to_kernel.cl", &file_len);
if(source){
program = clCreateProgramWithSource(context, 1, (const char **)&src_file, NULL, &status);
}
我有一个关于将 OpenCL 代码从 Linux(它工作的地方)移植到 Mac OS X 10.9.5.
的问题在我使用 malloc 的代码部分,当我启动可执行文件时,出现以下错误:
OpenCLSimu(13400,0x7fff7da7c310) malloc: *** mach_vm_map(size=1556840295209897984) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
可以看到,申请的内存很大:1556840295209897984字节,所以分配失败。
这是分配部分的例程(在我的例子中 NumBodies 是 30720):
int OpenCLSimu::setup()
{
// Make sure numParticles is multiple of group size
numBodies = (cl_int)(((size_t) getNumParticles()
< groupSize) ? groupSize : getNumParticles());
initPos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(initPos, "Failed to allocate host memory. (initPos)");
initVel = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(initVel, "Failed to allocate host memory. (initVel)");
pos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(pos, "Failed to allocate host memory. (pos)");
vel= (cl_double*) malloc(numBodies * sizeof(cl_double4));
CHECK_ALLOCATION(vel, "Failed to allocate host memory. (vel)");
return NBODY_SUCCESS;
}
我不知道是否存在关系,但我在 https://bugs.openjdk.java.net/browse/JDK-8043507(使用 Java 语言)上发现在 OS X 上,我们必须指定 uint32_t 输入尺寸。
可能这个问题来自于我用于编译的clang编译器。
CC = /usr/bin/clang
CXX = /usr/bin/clang++
DEFINES = -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS = -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.9 -Wall -W $(DEFINES)
CXXFLAGS = -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.9 -Wall -W $(DEFINES)
我还尝试将 numBodies 设置为 3072 以查看 mach_vm_map
的巨大尺寸,我得到:
malloc: * mach_vm_map(size=868306322687266816) 失败(错误代码=3) * 错误:无法分配区域 *** 在 malloc_error_break 中设置断点以调试
我注意到这些尺寸总是随着不同的执行而变化。
最后,我将 pos
和 vel
数组的 Linux 版本放入上述例程中:
pos = (cl_double*)memalign(16, numBodies * sizeof(cl_double4));
vel = (cl_double*)memalign(16, numBodies * sizeof(cl_double4));
而不是 malloc 使用:
pos = (cl_double*) malloc(numBodies * sizeof(cl_double4));
vel= (cl_double*) malloc(numBodies * sizeof(cl_double4));
我看到在 OS X 上,数据默认在 16 字节边界对齐,这就是为什么我将 memalign
替换为 malloc
以代替 MacOS版本
如果有人有线索,那就太好了。
提前致谢。
更新:
错误发生在“cout << size of source =" << sourceSize << endl
”和“cout << "status =" << status << endl
”之间,因此在clCreateProgramWithSource
方法上失败:
// create a CL program using the kernel source
const char *kernelName = "Simu_Kernels.cl";
FILE *fp = fopen(kernelName, "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
char *source = (char*)malloc(10000);
int sourceSize = fread( source, 1, 10000, fp);
fclose(fp);
cout << "size of source =" << sourceSize << endl;
// Create a program from the kernel source
program = clCreateProgramWithSource(context, 1, (const char **)&source, (const size_t *)&sourceSize, &status);
//program = clCreateProgramWithSource(context, 1, (const char **)&source, NULL, &status);
cout << "status =" << status << endl;
cout << "current_device =" << current_device<< endl;
在执行时,我得到:
Selected Platform Vendor : Apple
Device 0 : Iris Pro Device ID is 0x1024500
Device 1 : GeForce GT 750M Device ID is 0x1022700
size of source =2026
OpenCLSimu(15802,0x7fff7da7c310) malloc: *** mach_vm_map(size=59606861803950080) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
status =-6
和status = -6
对应一个CL_OUT_OF_HOST_MEMORY
我让你注意到我的 macbook 上有 2 个 GPU 单元(Iris Pro Device 和 GeForce GT 750M)。我对两个设备都有同样的错误。
尝试创建程序如下:
static char* Read_Source_File(
const char *filename,
size_t *file_len)
{
long int
size = 0,
res = 0;
char *src = NULL;
FILE *file = fopen(filename, "rb");
if (!file) return NULL;
if (fseek(file, 0, SEEK_END))
{
fclose(file);
return NULL;
}
size = ftell(file);
*file_len = size;
if (size == 0)
{
fclose(file);
return NULL;
}
rewind(file);
src = (char *)calloc(size + 1, sizeof(char));
if (!src)
{
src = NULL;
fclose(file);
return src;
}
res = fread(src, 1, sizeof(char) * size, file);
if (res != sizeof(char) * size)
{
fclose(file);
free(src);
return (char*)NULL;
}
src[size] = '[=10=]'; /* NULL terminated */
fclose(file);
return src;
}
size_t file_len;
char *source = Read_Source_File("path_to_kernel.cl", &file_len);
if(source){
program = clCreateProgramWithSource(context, 1, (const char **)&src_file, NULL, &status);
}