How to install Cilk on Max OS X
I got interested in Cilk, a concurrent language for parallel programming. Then I tried to install Cilk on my MacBook with OS X 10.6.4 and Intel Core 2 Duo, however, there were 3 problems to install it. I'd like to introduce these problems and my solutions: we have to modify 3 headers.
Environment
- Mac OS X 10.6.4 Snow Leopard
- Cilk 5.4.6 (cilk-5.4.6.tar.gz)
How to install
note: '$' is the prompt of Terminal.app
1. extract tar.gz
$ tar xzf cilk-5.4.6.tar.gz
2. move into the directory
$ cd cilk-5.4.6
3. run configure
$ ./configure
see ./configure --help if you want make additional configuration.
4. make
$ make
We'll encounter 3 problems during the compile process.
5. install
$ sudo make install
6. confirm PATH
If you didn't make any additional configuration, the compiler 'cilkc' will be installed on /usr/local/bin. Confirm if PATH includes this directory.
$ echo $PATH
If not, add it to PATH
$ export PATH=/usr/local/bin:$PATH
First Problem: Unnamed Bitfield
In the first make, we'll see this error.
../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o hello.o hello.cilk ../support/cilkclocal -g -O2 -o hello hello.o -lm ../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o fib.o fib.cilk /usr/include/mach/i386/_structs.h:97: syntax error Compilation Failed: 1 error, 0 warnings Error: failed running cilk2c make[2]: *** [fib.o] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2
This is caused by that mach/i386/_structs.h has unnamed bitfield and Cilk seems to be unable to handle unnamed bitfield. So we have to modify it.
89 _STRUCT_FP_CONTROL 90 { 91 unsigned short __invalid :1, 92 __denorm :1, 93 __zdiv :1, 94 __ovrfl :1, 95 __undfl :1, 96 __precis :1, 97 :2, // unnamed bitfield 98 __pc :2,
The best way would giving the bitfields some sort of name. We'll see same error in line 111 and 112. So, modify 3 lines.
/usr/include% diff mach/i386/_structs.h mach/i386/_structs.h.orginal 97c97 < __tmp1 :2, --- > :2, 111,112c111,112 < __tmp2 /*inf*/ :1, < __tmp3 :3; --- > /*inf*/ :1, > :3;
Second Problem: Declaration without a Variable
In the second make, we'll see an error saying "declaration without a variable"
../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o hello.o hello.cilk ../support/cilkclocal -g -O2 -o hello hello.o -lm ../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o fib.o fib.cilk /usr/include/stdlib.h:272: syntax error /usr/include/stdlib.h:272: declaration without a variable Compilation Failed: 2 errors, 0 warnings Error: failed running cilk2c make[2]: *** [fib.o] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2
Let's see stdlib.h.
int atexit_b(void (^)(void));
Cilk compiler seems not to allow to use '^' in names of function pointers. So, we have to give them names.
Replace all '^' of function pointers in function declaration in #ifdef __BLOCKS__ ~ #endif blocks, by some sort of name, like 'x'.
/usr/include% diff stdlib.h stdlib.h.original 272c272 < int atexit_b(void (x)(void)); --- > int atexit_b(void (^)(void)); 274c274 < size_t, int (x)(const void *, const void *)); --- > size_t, int (^)(const void *, const void *)); 301c301 < int (x)(const void *, const void *)); --- > int (^)(const void *, const void *)); 307c307 < int (x)(const void *, const void *)); --- > int (^)(const void *, const void *)); 313c313 < int (x)(const void *, const void *)); --- > int (^)(const void *, const void *)); 319c319 < int (x)(const void *, const void *)); --- > int (^)(const void *, const void *));
Third Problem: memcpy's operands have incompatible types
In the third make, we'll encounter the final error, "operands have incompatible types".
../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o testall.o testall.cilk testall.cilk:1194: Warning: implicitly declaring function to return int: __builtin_object_size() testall.cilk:1194: Warning: implicitly declaring function to return int: __builtin___sprintf_chk() testall.cilk:365: warning: ‘__unused__’ attribute ignored (snip) testall.cilk:1277: warning: ‘__unused__’ attribute ignored testall.cilk:1277: warning: ‘__unused__’ attribute ignored ../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o rand.o rand.cilk ../support/cilkclocal -g -O2 -o testall testall.o rand.o -lm ../support/cilkclocal -DHAVE_CONFIG_H -I. -I.. -I../runtime -g -O2 -c -o ck.o ck.cilk /usr/include/secure/_string.h:58: Warning: implicitly declaring function to return int: __builtin_object_size() /usr/include/secure/_string.h:58: Warning: implicitly declaring function to return int: __builtin___memcpy_chk() (snip) /usr/include/secure/_string.h:139: Warning: implicitly declaring function to return int: __builtin___strncat_chk() /usr/include/secure/_string.h:58: Warning: assignment of integer value to pointer (snip) /usr/include/secure/_string.h:139: Warning: assignment of integer value to pointer ck.cilk:223: Compilation Failed: 1 error, 17 warnings Error: failed running cilk2c make[2]: *** [ck.o] Error 1 make[1]: *** [all-recursive] Error 1 make: *** [all] Error 2
This error seems to be caused by using secure/_string.h. In secure/_string.h, memcpy and other functions are defined as macro and it cause type inconsistency.
#undef memcpy (snip) #define memcpy(dest, src, len) \ ((__darwin_obsz0 (dest) != (size_t) -1) \ ? __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) \ : __inline_memcpy_chk (dest, src, len)) static __inline void * __inline_memcpy_chk (void *__dest, const void *__src, size_t __len) { return __builtin___memcpy_chk (__dest, __src, __len, __darwin_obsz0(__dest)); }
The easiest way is not to use this secure/_string.h. Comment out the line including secure/_string.h.
# not recommended!! /usr/include% diff string.h string.h.original 148c148 < //#include <secure/_string.h> --- > #include <secure/_string.h>
Note that, this change might make an important effect on other softwares compiled on the Mac. So, it would be better modify only when compile Cilk programs using memcpy etc..
So, one possible solution is like this:
/usr/include% diff string.h string.h.original 146c146 < #if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus) && !defined (__CILK) --- > #if defined (__GNUC__) && _FORTIFY_SOURCE > 0 && !defined (__cplusplus)
then,
alias cilkc='cilkc -D__CILK'
Conclusion
After making these 3 modification, your make will successfully finish. Then, do make install.
I've confirmed that Cilk worked fine on my MacBook :)
/Users/yuyarin/Program/Cilk% vim fib.cilk /Users/yuyarin/Program/Cilk% cilkc -O2 fib.cilk -o fib /Users/yuyarin/Program/Cilk% time ./fib --nproc 1 40 Result: 102334155 ./fib --nproc 1 40 5.84s user 0.01s system 99% cpu 5.880 total /Users/yuyarin/Program/Cilk% time ./fib --nproc 2 40 Result: 102334155 ./fib --nproc 2 40 6.02s user 0.01s system 193% cpu 3.114 total
おまけ
set highlight for CilkKeyword, CilkStatement, CilkType, CilkFunction, CilkVariable.