From 0af94769e088ebf3a642d927d65f52313b9bf13e Mon Sep 17 00:00:00 2001 From: scchan Date: Sat, 26 Mar 2016 23:04:54 -0500 Subject: [PATCH 1/7] gpu link support for static library --- lib/clamp-link.in | 269 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 266 insertions(+), 3 deletions(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index 1208f317e0a..ad55f45866a 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -119,6 +119,221 @@ _find_object() { ARGS="$@" + +USE_NEW_LINK=1 + + +NEW_LINK_KERNEL_ARGS="" +NEW_LINK_HOST_ARGS="" +NEW_LINK_OTHER_ARGS="" +NEW_LINK_CPU_ARG="" + +TEMP_AR_DIRS=() + +if [ $USE_NEW_LINK == 1 ]; then + +# gather a list of library search paths +LIB_SEARCH_PATHS=() +for ARG in $ARGS +do + # matches -L + if [[ "$ARG" =~ ^-L[^[:space:]]+$ ]]; then + + if [ $VERBOSE == 1 ]; then + echo "adding library search path: ${ARG:2}" + fi + LIB_SEARCH_PATHS+=( ${ARG:2} ) + fi +done + + + + +for ARG in $ARGS +do + + #################################### + # parse the simple switches first... + #################################### + + if [ $ARG == "--verbose" ]; then + VERBOSE=1 + continue + fi + + if [ $ARG == "--disable-opencl" ]; then + LOWER_OPENCL=0 + continue + fi + + if [ $ARG == "--disable-hsa" ]; then + LOWER_HSA=0 + continue + fi + + + + ##################################### + # detect object or static library + ##################################### + + OBJS_TO_PROCESS=() + + + if [[ "$ARG" =~ [^[:space:]]+\.cpu$ ]]; then + + cp $ARG $TEMP_DIR/kernel_cpu.o + NEW_LINK_CPU_ARG=$NEW_LINK_CPU_ARG" "$TEMP_DIR/kernel_cpu.o + + elif [[ "$ARG" =~ [^[:space:]]+\.o$ ]]; then + # detected a .o file + if [ $VERBOSE == 1 ]; then + echo "detect object file to process further: $ARG" + fi + + OBJS_TO_PROCESS+=( $ARG ) + elif [[ "$ARG" =~ ^-l[^[:space:]]+$ ]] || [[ "$ARG" =~ [^[:space:]]+.a$ ]]; then + + # proccess a static library + + DETECTED_STATIC_LIBRARY="" + + # detected whether it's an -l option + if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then + + # expand the option into a library name + STATIC_LIB_NAME="lib${ARG:2}.a" + + if [ $VERBOSE == 1 ]; then + echo "looking for static library $STATIC_LIB_NAME" + fi + + # look for the static library in the library search paths + for LIB_PATH in "${LIB_SEARCH_PATHS[@]}" + do + FULL_LIB_PATH=$LIB_PATH"/"$STATIC_LIB_NAME + if [ -f $FULL_LIB_PATH ]; then + if [ $VERBOSE == 1 ]; then + echo "$FULL_LIB_PATH detected" + fi + DETECTED_STATIC_LIBRARY=$FULL_LIB_PATH; + break; + fi + done + else + # this is .a static library file specified at the commad line + if [ -f $ARG ]; then + DETECTED_STATIC_LIBRARY=$ARG + fi + fi # if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then + + + KERNEL_DETECTED="1" # 1 means NO .kernel detected in a static library! + if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then + + # we found a static library library + if [ $VERBOSE == 1 ]; then + echo "processing static library $DETECTED_STATIC_LIBRARY" + fi + + # detect whether the objects in the static library contain a .kernel section + KERNEL_DETECTED=`strings $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?` + if [[ $KERNEL_DETECTED == "0" ]]; then + + # .kernel section detected, extract the objects from the archieve + + if [ $VERBOSE == 1 ]; then + echo "kernel detected in $DETECTED_STATIC_LIBRARY" + fi + + CURRENT_DIR=$PWD + # extract the archive + FILE=`basename $DETECTED_STATIC_LIBRARY` + AR_TEMP_DIR=$TEMP_DIR"/"$FILE + + if [ $VERBOSE == 1 ]; then + echo "creating temp dir: $AR_TEMP_DIR" + fi + + mkdir -p $AR_TEMP_DIR + TEMP_AR_DIRS+=( $AR_TEMP_DIR ) + cd $AR_TEMP_DIR + `ar x $DETECTED_STATIC_LIBRARY` + + cd $CURRENT_DIR + + # store all the extract objects to process further + OBJS_TO_PROCESS=($(ls $AR_TEMP_DIR/*.o)) + + fi # if [[ $KERNEL_DETECTED == "0" ]]; then + fi # if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then + elif [ -f $ARG ]; then + # an object file but doesn't have an .o extension?? + file_output=`file $ARG | grep 'ELF 64-bit LSB relocatable, x86-64'` + readelf_output=`readelf -h $ARG | grep 'Relocatable file'` + if [ ! -z "$file_output" ] && [ ! -z "$readelf_output" ]; then + OBJS_TO_PROCESS+=( $ARG ) + fi + fi + + + # no objects to further process, pass the original args down to the host linker + if [ ${#OBJS_TO_PROCESS[@]} == 0 ]; then + # no objects to further process, pass the original args down to the host linker + if [ $VERBOSE == 1 ]; then + echo "passing down link args: $ARG" + fi + NEW_LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS" "$ARG + continue + fi + + # processs the objects we put aside + for OBJ in "${OBJS_TO_PROCESS[@]}" + do + if [ $VERBOSE == 1 ]; then + echo "processing $OBJ" + fi + + # detect whether the objects in the static library contain a .kernel section + KERNEL_DETECTED=`strings $OBJ | grep -q "\.kernel"; echo $?` + if [[ $KERNEL_DETECTED == "0" ]]; then + + FILE=`basename $OBJ` # remove path + FILENAME=${FILE%.*} + KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc + HOST_FILE=$TEMP_DIR/$FILENAME.host.o + + # extract kernel section + objcopy -O binary -j .kernel $OBJ $KERNEL_FILE + + # extract host section + objcopy -R .kernel $OBJ $HOST_FILE + + # strip all symbols specified in symbol.txt from $HOST_FILE + objcopy @$CXXAMP_SERIALIZE_SYMBOL_FILE $HOST_FILE $HOST_FILE.new 2> /dev/null + if [ -f $HOST_FILE.new ]; then + mv $HOST_FILE.new $HOST_FILE + fi + + # find cxxamp_serialize symbols and save them into symbol.txt + objdump -t $HOST_FILE -j .text 2> /dev/null | grep "g.*__cxxamp_serialize" | awk '{print "-L"$6}' >> $CXXAMP_SERIALIZE_SYMBOL_FILE + + NEW_LINK_KERNEL_ARGS=$NEW_LINK_KERNEL_ARGS" "$KERNEL_FILE + NEW_LINK_HOST_ARGS=$NEW_LINK_HOST_ARGS" "$HOST_FILE + else + NEW_LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS" "$OBJ + fi + + + done # for OBJ in "${OBJS_TO_PROCESS[@]}" +done + +else # if [ $USE_NEW_LINK == 1 ]; then + +############################ +# Old argument processing +############################ + for ARG in $ARGS do if [ -f $ARG ]; then @@ -127,6 +342,15 @@ do CPUFILE=${FILE%.cpu} ISCRT=${ARG#/usr} # exception for objects under /usr ISLIB=${ARG#/lib} # exception for objects under /lib + + echo "file: $FILE" + echo "filename: $FILENAME" + echo "cpufile: $CPUFILE" + echo "iscrt: $ISCRT" + echo "islib: $ISLIB" + echo "" + + if [ $FILENAME != $FILE ] && [ $ISCRT == $ARG ] && [ $ISLIB == $ARG ]; then KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc HOST_FILE=$TEMP_DIR/$FILENAME.host.o @@ -164,9 +388,43 @@ do LINK_OTHER_ARGS=$LINK_OTHER_ARGS" "$ARG fi done -#echo "kernel args:"$LINK_KERNEL_ARGS -#echo "host args:"$LINK_HOST_ARGS -#echo "other args:"$LINK_OTHER_ARGS + +if [ $VERBOSE == 1 ]; then + echo "kernel args: "$LINK_KERNEL_ARGS + echo "" + echo "host args: "$LINK_HOST_ARGS + echo "" + echo "other args: "$LINK_OTHER_ARGS + echo "" +fi + +################################### +# End of old argument processing +################################### + +fi + + + +if [ $USE_NEW_LINK == 1 ]; then + +if [ $VERBOSE == 1 ]; then + echo "new kernel args: "$NEW_LINK_KERNEL_ARGS + echo "" + echo "new host args: "$NEW_LINK_HOST_ARGS + echo "" + echo "new other args: "$NEW_LINK_OTHER_ARGS +fi + +if [ $VERBOSE == 1 ]; then + echo "replacing old link args with new link args" +fi +LINK_KERNEL_ARGS=$NEW_LINK_KERNEL_ARGS +LINK_HOST_ARGS=$NEW_LINK_HOST_ARGS +LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS + +fi + # linker return value ret=0 @@ -339,6 +597,11 @@ if [ -e $CXXAMP_SERIALIZE_SYMBOL_FILE ]; then rm $CXXAMP_SERIALIZE_SYMBOL_FILE # __cxxamp_serialize symbols fi +for TD in "${TEMP_AR_DIRS[@]}" +do + rm -rf $TD +done + if [ -d $TEMP_DIR ]; then rm -f $TEMP_DIR/* rmdir $TEMP_DIR From 321e586344ff98ff72f4df0124e02d507ea29355 Mon Sep 17 00:00:00 2001 From: scchan Date: Sun, 27 Mar 2016 11:50:23 -0500 Subject: [PATCH 2/7] gpu static link: -L option supports relative path --- lib/clamp-link.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index ad55f45866a..99e57d1a880 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -142,7 +142,13 @@ do if [ $VERBOSE == 1 ]; then echo "adding library search path: ${ARG:2}" fi - LIB_SEARCH_PATHS+=( ${ARG:2} ) + + if [[ "$ARG" =~ ^-L\/[^[:space:]]+$ ]]; then + # this is an absolute path + LIB_SEARCH_PATHS+=( ${ARG:2} ) + else + LIB_SEARCH_PATHS+=( $PWD"/"${ARG:2} ) + fi fi done From dbbc2951f4e35a258fff633c732d399507e2fdb9 Mon Sep 17 00:00:00 2001 From: scchan Date: Sun, 27 Mar 2016 12:11:20 -0500 Subject: [PATCH 3/7] cleanup verbose mode --- lib/clamp-link.in | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index 99e57d1a880..d6d23071925 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -119,10 +119,9 @@ _find_object() { ARGS="$@" - +# flag to switch to the new arg parsing algorithm USE_NEW_LINK=1 - NEW_LINK_KERNEL_ARGS="" NEW_LINK_HOST_ARGS="" NEW_LINK_OTHER_ARGS="" @@ -132,6 +131,15 @@ TEMP_AR_DIRS=() if [ $USE_NEW_LINK == 1 ]; then +# detect the verbose flags before doing anything +if [[ "$ARGS" =~ --verbose ]]; then + VERBOSE=1 +fi +#very verbose +#VERBOSE=2 + + + # gather a list of library search paths LIB_SEARCH_PATHS=() for ARG in $ARGS @@ -139,7 +147,7 @@ do # matches -L if [[ "$ARG" =~ ^-L[^[:space:]]+$ ]]; then - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "adding library search path: ${ARG:2}" fi @@ -161,11 +169,6 @@ do #################################### # parse the simple switches first... #################################### - - if [ $ARG == "--verbose" ]; then - VERBOSE=1 - continue - fi if [ $ARG == "--disable-opencl" ]; then LOWER_OPENCL=0 @@ -193,7 +196,7 @@ do elif [[ "$ARG" =~ [^[:space:]]+\.o$ ]]; then # detected a .o file - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "detect object file to process further: $ARG" fi @@ -210,7 +213,7 @@ do # expand the option into a library name STATIC_LIB_NAME="lib${ARG:2}.a" - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "looking for static library $STATIC_LIB_NAME" fi @@ -219,7 +222,7 @@ do do FULL_LIB_PATH=$LIB_PATH"/"$STATIC_LIB_NAME if [ -f $FULL_LIB_PATH ]; then - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "$FULL_LIB_PATH detected" fi DETECTED_STATIC_LIBRARY=$FULL_LIB_PATH; @@ -238,7 +241,7 @@ do if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then # we found a static library library - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "processing static library $DETECTED_STATIC_LIBRARY" fi @@ -248,7 +251,7 @@ do # .kernel section detected, extract the objects from the archieve - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "kernel detected in $DETECTED_STATIC_LIBRARY" fi @@ -257,7 +260,7 @@ do FILE=`basename $DETECTED_STATIC_LIBRARY` AR_TEMP_DIR=$TEMP_DIR"/"$FILE - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "creating temp dir: $AR_TEMP_DIR" fi @@ -286,7 +289,7 @@ do # no objects to further process, pass the original args down to the host linker if [ ${#OBJS_TO_PROCESS[@]} == 0 ]; then # no objects to further process, pass the original args down to the host linker - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "passing down link args: $ARG" fi NEW_LINK_OTHER_ARGS=$NEW_LINK_OTHER_ARGS" "$ARG @@ -296,7 +299,7 @@ do # processs the objects we put aside for OBJ in "${OBJS_TO_PROCESS[@]}" do - if [ $VERBOSE == 1 ]; then + if [ $VERBOSE == 2 ]; then echo "processing $OBJ" fi From 57d2bda6d244deef11523caad30cf45da41d3b1b Mon Sep 17 00:00:00 2001 From: scchan Date: Sun, 27 Mar 2016 13:53:41 -0500 Subject: [PATCH 4/7] static library test --- tests/Unit/StaticLibrary/static_library1.cpp | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/Unit/StaticLibrary/static_library1.cpp diff --git a/tests/Unit/StaticLibrary/static_library1.cpp b/tests/Unit/StaticLibrary/static_library1.cpp new file mode 100644 index 00000000000..b86357c6c50 --- /dev/null +++ b/tests/Unit/StaticLibrary/static_library1.cpp @@ -0,0 +1,44 @@ +// RUN: %hc -DSTATIC_LIB %s -c -o %T/static_library1.o +// RUN: ar rcs %T/libstatic_library1.a %T/static_library1.o +// RUN: %hc %s -L%T -lstatic_library1 -o %t.out && %t.out + +#include +#include + +extern "C" int sum(hc::array_view& input); + +#ifdef STATIC_LIB + +int sum(hc::array_view& input) { + + hc::array_view s(1); + s[0]=0; + + hc::parallel_for_each(input.get_extent(), [=](hc::index<1> idx) [[hc]] { + if (idx[0]==0) { + int num = input.get_extent()[0]; + for (int i = 0; i < num; i++) { + s[0]+=input[i]; + } + } + }).wait(); + + return s[0]; +} + +#else + +int main() { + + hc::array_view av(64); + for (int i = 0;i < 64; i++) + av[i] = i; + + int s = sum(av); + + // printf("sum: %d\n",s); + + return !(s==2016); +} + +#endif From 81fcbce57e52b35a9ad36915b9571a505e48c029 Mon Sep 17 00:00:00 2001 From: scchan Date: Mon, 28 Mar 2016 08:48:24 -0500 Subject: [PATCH 5/7] remove debug messages --- lib/clamp-link.in | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index d6d23071925..3ca27e1632c 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -352,14 +352,6 @@ do ISCRT=${ARG#/usr} # exception for objects under /usr ISLIB=${ARG#/lib} # exception for objects under /lib - echo "file: $FILE" - echo "filename: $FILENAME" - echo "cpufile: $CPUFILE" - echo "iscrt: $ISCRT" - echo "islib: $ISLIB" - echo "" - - if [ $FILENAME != $FILE ] && [ $ISCRT == $ARG ] && [ $ISLIB == $ARG ]; then KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc HOST_FILE=$TEMP_DIR/$FILENAME.host.o From d69acde29425f6925bd1874cb78d1c78583666ec Mon Sep 17 00:00:00 2001 From: scchan Date: Mon, 28 Mar 2016 08:54:49 -0500 Subject: [PATCH 6/7] use objdump to detect .kernel section --- lib/clamp-link.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index 3ca27e1632c..119fc37d405 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -246,7 +246,7 @@ do fi # detect whether the objects in the static library contain a .kernel section - KERNEL_DETECTED=`strings $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?` + KERNEL_DETECTED=`objdump -t $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?` if [[ $KERNEL_DETECTED == "0" ]]; then # .kernel section detected, extract the objects from the archieve @@ -304,7 +304,7 @@ do fi # detect whether the objects in the static library contain a .kernel section - KERNEL_DETECTED=`strings $OBJ | grep -q "\.kernel"; echo $?` + KERNEL_DETECTED=`objdump -t $OBJ | grep -q "\.kernel"; echo $?` if [[ $KERNEL_DETECTED == "0" ]]; then FILE=`basename $OBJ` # remove path From 8f7a4b1343dd0a328d5b553b220ac71e2fc24947 Mon Sep 17 00:00:00 2001 From: scchan Date: Mon, 28 Mar 2016 08:57:05 -0500 Subject: [PATCH 7/7] rename the KERNEL_DETECTED variable --- lib/clamp-link.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/clamp-link.in b/lib/clamp-link.in index 119fc37d405..d5bdf5675e5 100755 --- a/lib/clamp-link.in +++ b/lib/clamp-link.in @@ -237,7 +237,7 @@ do fi # if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then - KERNEL_DETECTED="1" # 1 means NO .kernel detected in a static library! + KERNEL_UNDETECTED="1" if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then # we found a static library library @@ -246,8 +246,8 @@ do fi # detect whether the objects in the static library contain a .kernel section - KERNEL_DETECTED=`objdump -t $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?` - if [[ $KERNEL_DETECTED == "0" ]]; then + KERNEL_UNDETECTED=`objdump -t $DETECTED_STATIC_LIBRARY | grep -q "\.kernel"; echo $?` + if [[ $KERNEL_UNDETECTED == "0" ]]; then # .kernel section detected, extract the objects from the archieve @@ -274,7 +274,7 @@ do # store all the extract objects to process further OBJS_TO_PROCESS=($(ls $AR_TEMP_DIR/*.o)) - fi # if [[ $KERNEL_DETECTED == "0" ]]; then + fi # if [[ $KERNEL_UNDETECTED == "0" ]]; then fi # if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then elif [ -f $ARG ]; then # an object file but doesn't have an .o extension?? @@ -304,8 +304,8 @@ do fi # detect whether the objects in the static library contain a .kernel section - KERNEL_DETECTED=`objdump -t $OBJ | grep -q "\.kernel"; echo $?` - if [[ $KERNEL_DETECTED == "0" ]]; then + KERNEL_UNDETECTED=`objdump -t $OBJ | grep -q "\.kernel"; echo $?` + if [[ $KERNEL_UNDETECTED == "0" ]]; then FILE=`basename $OBJ` # remove path FILENAME=${FILE%.*}