Skip to content

Commit

Permalink
Merge pull request #2 from scchan/gpu_link_static_lib
Browse files Browse the repository at this point in the history
GPU link - support linking static library
  • Loading branch information
whchung committed Mar 28, 2016
2 parents ec7664a + 8f7a4b1 commit 30418b8
Show file tree
Hide file tree
Showing 2 changed files with 311 additions and 3 deletions.
270 changes: 267 additions & 3 deletions lib/clamp-link.in
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,230 @@ _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=""
NEW_LINK_CPU_ARG=""

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
do
# matches -L<path>
if [[ "$ARG" =~ ^-L[^[:space:]]+$ ]]; then

if [ $VERBOSE == 2 ]; then
echo "adding library search path: ${ARG:2}"
fi

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




for ARG in $ARGS
do

####################################
# parse the simple switches first...
####################################

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 == 2 ]; 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<library naem> option
if [[ "$ARG" =~ ^-l[^[:space:]]+$ ]]; then

# expand the option into a library name
STATIC_LIB_NAME="lib${ARG:2}.a"

if [ $VERBOSE == 2 ]; 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 == 2 ]; 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_UNDETECTED="1"
if [[ $DETECTED_STATIC_LIBRARY != "" ]]; then

# we found a static library library
if [ $VERBOSE == 2 ]; then
echo "processing static library $DETECTED_STATIC_LIBRARY"
fi

# detect whether the objects in the static library contain a .kernel section
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

if [ $VERBOSE == 2 ]; 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 == 2 ]; 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_UNDETECTED == "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 == 2 ]; 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 == 2 ]; then
echo "processing $OBJ"
fi

# detect whether the objects in the static library contain a .kernel section
KERNEL_UNDETECTED=`objdump -t $OBJ | grep -q "\.kernel"; echo $?`
if [[ $KERNEL_UNDETECTED == "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
Expand All @@ -127,6 +351,7 @@ do
CPUFILE=${FILE%.cpu}
ISCRT=${ARG#/usr} # exception for objects under /usr
ISLIB=${ARG#/lib} # exception for objects under /lib

if [ $FILENAME != $FILE ] && [ $ISCRT == $ARG ] && [ $ISLIB == $ARG ]; then
KERNEL_FILE=$TEMP_DIR/$FILENAME.kernel.bc
HOST_FILE=$TEMP_DIR/$FILENAME.host.o
Expand Down Expand Up @@ -164,9 +389,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
Expand Down Expand Up @@ -339,6 +598,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
Expand Down
44 changes: 44 additions & 0 deletions tests/Unit/StaticLibrary/static_library1.cpp
Original file line number Diff line number Diff line change
@@ -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 <cstdio>
#include <hc.hpp>

extern "C" int sum(hc::array_view<int,1>& input);

#ifdef STATIC_LIB

int sum(hc::array_view<int,1>& input) {

hc::array_view<int,1> 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<int,1> 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

0 comments on commit 30418b8

Please sign in to comment.