Альтернатива shed_getaffinity, cpu_set_t и т. Д.?
Так что я нуб, когда дело доходит до такого рода вещей.
Я изо всех сил пытаюсь скомпилировать климатическую модель на macOS, и я свел ее к тому, что здесь происходит:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include <sys/resource.h>
#include <sys/syscall.h>
static pid_t gettid(void)
{
return syscall(__NR_gettid);
}
/*
* Returns this thread's CPU affinity, if bound to a single core,
* or else -1.
*/
int get_cpu_affinity(void)
{
cpu_set_t coremask; /* core affinity mask */
CPU_ZERO(&coremask);
if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
fprintf(stderr,"Unable to get thread %d affinity.
%s\n",gettid(),strerror(errno));
}
int cpu;
int first_cpu = -1; /* first CPU in range */
int last_cpu = -1; /* last CPU in range */
for (cpu=0;cpu < CPU_SETSIZE;cpu++) {
if (CPU_ISSET(cpu,&coremask)) {
if (first_cpu == -1) {
first_cpu = cpu;
} else {
last_cpu = cpu;
}
}
}
return (last_cpu == -1) ? first_cpu : -1;
}
int get_cpu_affinity_(void) { return get_cpu_affinity(); } /* Fortran interface */
/*
* Set CPU affinity to one core.
*/
void set_cpu_affinity( int cpu )
{
cpu_set_t coremask; /* core affinity mask */
CPU_ZERO(&coremask);
CPU_SET(cpu,&coremask);
if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
fprintf(stderr,"Unable to set thread %d affinity. %s\n",gettid(),strerror(errno));
}
}
void set_cpu_affinity_(int *cpu) { set_cpu_affinity(*cpu); } /* Fortran interface */
При компиляции я получаю пару ошибок:
Первый - идентификатор "cpu_set_t" не определен, Второй - идентификатор "CPU_SETSIZE" не определен
Я выполнил поиск в Google, и мне кажется, что sched_getaffinitiy(), cpu_set_t и, возможно, некоторые другие вещи отсутствуют в macOS.
Со всеми видами программирования на Си я действительно не в себе. Мне было интересно, если кто-нибудь здесь знает альтернативный способ сделать это для MacOS и как я мог бы сделать это.
Я приложил полный отчет об ошибке ниже.
С уважением,
Нил:)
Полный отчет об ошибках:
(python2) salvare:MASTERS Neil$ python run.py
Working directory for exp 'playground' already exists
RRTM compilation disabled. Namelist set to gray radiation.
Writing path_names to '/Users/Neil/MASTERS/ISCA_TEMP/playground/path_names'
Running compiler
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 21: module: command not found
loadmodules
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 3: module: command not found
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 4: module: command not found
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 5: module: command not found
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 6: module: command not found
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 23: module: command not found
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 24: ulimit: stack size: cannot modify limit: Operation not permitted
./compile_mppn.sh: line 13: module: command not found
./compile_mppn.sh: line 14: module: command not found
./compile_mppn.sh: line 15: module: command not found
- mppnccombine.c:162:24: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
sprintf(outfilename,argv[outputarg]); outlen=strlen(outfilename);
^~~~~~~~~~~~~~~
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
^~~~~~~~~~~
mppnccombine.c:162:24: note: treat the string as an argument to avoid this
sprintf(outfilename,argv[outputarg]); outlen=strlen(outfilename);
^
"%s",
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
^
1 warning generated.
ln: /Users/Neil/MASTERS/ISCA_TEMP/playground/exec/mppnccombine.x: File exists
Makefile is ready.
mpicc -Duse_libMPI -Duse_netCDF -Duse_LARGEFILE -DINTERNAL_FILE_NML -DOVERLOAD_C8 -DRRTM_NO_COMPILE -I/usr/local/include -D__IFC -c /Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c
......................................................................................................................../Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(35): error: identifier "__NR_gettid" is undefined
eturn syscall(__NR_gettid);
^
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(44): error: identifier "cpu_set_t" is undefined
cpu_set_t coremask; /* core affinity mask */
^
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(47): error: identifier "cpu_set_t" is undefined
if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
^
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(54): error: identifier "CPU_SETSIZE" is undefined
for (cpu=0;cpu < CPU_SETSIZE;cpu++) {
^
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(75): error: identifier "cpu_set_t" is undefined
cpu_set_t coremask; /* core affinity mask */
^
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(79): error: identifier "cpu_set_t" is undefined
if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
^
compilation aborted for /Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c (code 2)
make: *** [affinity.o] Error 2
ERROR: mkmf failed for fms_moist
CRITICAL - Compilation failed.
Traceback (most recent call last):
File "run.py", line 25, in <module>
exp.compile()
File "/Users/Neil/MASTERS/Isca/src/extra/python/gfdl/experiment.py", line 298, in compile
raise e
sh.ErrorReturnCode_1:
RAN: /bin/bash /Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh
STDOUT:
STDERR:
1 ответ
Ваш поиск в Google поставил вас на правильный путь - sched_getaffinity()
и cpu_set_t
используемая им структура специфична для linux и доступна не на всех платформах. Mac OSX в частности, кажется, скучает по ним.
Однако есть альтернативы. Я нашел сообщение в блоге от того, кто портировал код на OSX, и нашел альтернативу, используя sysctlbyname()
, Код на этом сайте переопределён sched_getaffinity()
на Mac OSX, запросив machdep.cpu.core_count
и используя это, чтобы построить свою собственную версию cpu_set_t
,