gen_co.sh 5.73 KB
Newer Older
Xiaowei.zhang's avatar
Xiaowei.zhang committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash

usage(){
    cat << EOF

    Usage: $0 [-c <clang path>] [-d] -s|--asm <assembly file path>
    Option:
           -c <clang path>: optional
               if not specify clang path, use default: llvm/bin/clang in repository gemmPerf.

           -s|--asm <assembly file path>: required
               assembly file path must end with .s

EOF
}

gen_amdgcn_target(){
    amdgcn_target=$(grep -nr "\.amdgcn_target" $s_abs_path | awk '{print $NF}' | awk -F "\"" '{print $2}')
    amdgcn_target=${amdgcn_target#*--}
    [[ -n ${amdgcn_target} ]] || { echo "target-id null, exit"; exit -1; }
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- amdgcn_target: $amdgcn_target"
}

gen_co_from_s(){
    local co_dir=${PWD}/hsaco_kernel
    local o_dir=${PWD}/o_kernel
    [[ -d ${co_dir} ]] || mkdir -p ${co_dir}
    [[ -d ${o_dir} ]] || mkdir -p ${o_dir}

    local o_abs_dir_path
    local name_prefix
    local o_name
    local co_name
    o_abs_dir_path=$(dirname ${s_abs_path})
    name_prefix=$(basename ${s_abs_path})
    name_prefix=${name_prefix%.s}
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- name prefix: $name_prefix"
    o_name="${name_prefix}.o"
    co_name="${name_prefix}.co"

    ### Command: generate .o from .s:
    #grep "$2" $s_abs_path || { echo -e "\n*** Fatal: .amdgcn_target in .s not contain specified target-id: $2\n*** .s: $(grep ".amdgcn_target" $s_abs_path)"; exit -1; }
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- .s -> .o:\n     $ ${ASM_COMPILER} -x assembler -target amdgcn-amd-amdhsa -mcpu=${amdgcn_target} -c -o ${o_dir}/${o_name} ${s_abs_path}"
    ${ASM_COMPILER} -x assembler -target amdgcn-amd-amdhsa -mcpu=${amdgcn_target} -c -o ${o_dir}/${o_name} ${s_abs_path}
    [[ $? -eq 0 ]] || { echo -e "\n*** Fatal: $(basename $0) failure .s -> .o\n    $ ${ASM_COMPILER} -x assembler -target amdgcn-amd-amdhsa -mcpu=${amdgcn_target} -c -o ${o_dir}/${o_name} ${s_abs_path} "; exit -1; }
    o_abs_path=$(realpath -e ${o_dir}/${o_name})
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- .o dir: ${o_dir}\n--- .o path:\n    $(realpath -e ${o_dir}/${o_name})"

    ### Command: generate .hsaco/.co from .o:
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- .o -> .co:\n    $ ${ASM_COMPILER} -target amdgcn-amd-amdhsa -o ${co_dir}/${co_name} ${o_abs_path}"
    ${ASM_COMPILER} -target amdgcn-amd-amdhsa -o ${co_dir}/${co_name} ${o_abs_path}
    [[ $? -eq 0 ]] || { echo -e "\n*** Fatal: $(basename $0) failure .o -> .co\n    $ ${ASM_COMPILER} -target amdgcn-amd-amdhsa -o ${co_dir}/${co_name} ${o_abs_path}"; exit -1; }
    co_abs_path=$(realpath -e ${co_dir}/${co_name}) || exit -1
    [[ $DEBUG_MODE = true ]] && echo -e "\n--- .co dir: ${co_dir}\n--- .co path:\n    ${co_abs_path}"
    echo "${co_abs_path}"
}

check_getopt_exit_status(){
    local exit_status=$1
    if [[ $exit_status -eq 0 ]] && [[ $DEBUG_MODE = true ]]; then
        echo -e "--- Parsing Successfully."
    elif [[ $exit_status -eq 1 ]]; then
        echo -e "*** getopt(3) returns errors."
        exit -1
    elif [[ $exit_status -eq 2 ]]; then
        echo -e "*** Don't understand its own parameters"
        exit -1
    elif [[ $exit_status -eq 3 ]]; then
        echo -e "*** an internal error occurs like out-of-memory"
        exit -1
    elif [[ $exit_status -eq 4 ]] && [[ $DEBUG_MODE = true ]]; then
        echo -e "--- called with -T"
    fi
}

parse_option(){
    getopt -T
    if [[ $? -eq 4 ]]; then
        GETOPT_PARSE=$(getopt --name "${0}" --longoptions help,compiler:,asm:,debug --options hc:ds: -- "$@" 2>getopt_stderr.log)
        GETOPT_RET=$?
        if [[ -s getopt_stderr.log ]]; then
            echo -e "\n*** Fatal:"
            echo "*** $(cat getopt_stderr.log)"
            rm getopt_stderr.log
        fi
        check_getopt_exit_status $GETOPT_RET
        #if [[ $GETOPT_RET -eq 0 ]] ; then
        #    echo -e "--- option: ${GETOPT_PARSE}"
        #fi
    else
        echo -e "\n*** Fatal:"
        echo "*** getopt is an old version, Need enhanced version"
        exit -1
    fi
    eval set -- ${GETOPT_PARSE}
    while true;
    do
        case "$1" in
            -h|--help)
                usage
                exit 0
                ;;
            -c|--compiler)
                ASM_COMPILER=$(realpath -e $2) || exit -1
                shift 2
                ;;
            -s|--asm)
                ASM_FILE_PATH=$(realpath -e $2) || exit -1
                [[ $ASM_FILE_PATH =~ \.s$ ]] || { echo -e "\n*** Fatal: asm file not end with .s\n*** asm file: $ASM_FILE_PATH"; exit -1; }
                shift 2
                ;;
            -d|--debug)
                DEBUG_MODE=true
                shift
                ;;
            --)
                shift
                break
                ;;
            *)
                echo "unrecognized parameter:[$1] received, exit"
                exit -1
                ;;
        esac
    done
    if [[ -z $ASM_COMPILER ]]; then
        [[ $DEBUG_MODE = true ]] && echo -e "\n--- option no compiler option: -c/--compiler\n--- use default: /opt/rocm/llvm/bin/clang-18)"
        ASM_COMPILER=/opt/rocm/llvm/bin/clang-18 || exit -1
    fi
    if [[ -z $ASM_FILE_PATH ]]; then
        usage
        exit -1
    fi
    REMAIN_PARAMS_NUM=$#
    REMAIN_PARAMS=$@
    if [[ $DEBUG_MODE = true ]]; then
        echo "--- remaining parameter number: $#"
        echo "--- remaining parameter option: $@"
    fi
}

#####
# main
#####
# name
#    A word consisting only of alphanumeric characters and underscores,
#    and beginning with an alphabetic character or an underscore.
#    Also referred to as an identifier.
#####
ASM_COMPILER=
ASM_FILE_PATH=
REMAIN_PARAMS_NUM=
REMAIN_PARAMS=
DEBUG_MODE=false
parse_option $@
shift $(($#-$REMAIN_PARAMS_NUM))
#echo "\$@: $@"

#####
# compile .s -> .co
#####
s_abs_path=$ASM_FILE_PATH
co_abs_path=
gen_amdgcn_target
gen_co_from_s