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

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

おまけ

http://www.yuyarin.net/screenshot/20101026054112.png

vim syntax file for Cilk

set highlight for CilkKeyword, CilkStatement, CilkType, CilkFunction, CilkVariable.