Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPU link - support linking static library #2

Merged
merged 8 commits into from
Mar 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ARG may come from a relative path, need to canonicalize it here.

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`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scchan This line is causing errors. Caused when $DETECTED_STATIC_LIBRARY is from a relative path.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you see an error about libmcwamp.a when building the compiler, this patch #9 will fix that


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