#!/bin/bash
TOP_DIR=""
PKG_PATH=""
RUN_PKG_SAVE_PATH=""
OS_ARCH=$(uname -m)
PKG_NAME=""
SOC=""
OPP_PREFIX="opp"
parse_args() {
local arg
for arg in "$@"; do
case "$arg" in
--soc=*)
SOC="${arg#*=}"
;;
--top_dir=*)
TOP_DIR="${arg#*=}"
;;
--pkg_path=*)
PKG_PATH="${arg#*=}"
;;
--run_pkg_save_path=*)
RUN_PKG_SAVE_PATH="${arg#*=}"
;;
--pkg_name=*)
PKG_NAME="${arg#*=}"
;;
*)
echo "ERROR: Unknown param $arg" >&2
;;
esac
done
}
log() {
echo "$*"
}
die() {
log "ERROR: $*"
exit 1
}
ensure_dir() {
local dir="$1"
if [[ ! -d "$dir" ]]; then
log "Creating directory: $dir"
mkdir -p "$dir" || die "Failed to create directory $dir"
fi
}
ensure_file() {
local file="$1"
[[ -f "$file" ]] || die "Required file not found: $file"
}
log "Starting ops packaging process..."
parse_args "$@"
WORKDIR=${TOP_DIR}/${PKG_PATH}
TEMP_RUN_DIR="./run_files"
HOST_RUN_NAME="host.run"
HOST_EXTRACT_DIR="host"
MAKESELF_TARGET_DIR="build/makeself"
RUNFILE_TARGET_DIR="build/_CPack_Packages/makeself_staging"
PACKAGE_SCRIPT="$TOP_DIR/open_source/cann-cmake/scripts/package/package.py"
MERGE_SCRIPT="$TOP_DIR/open_source/cann-cmake/scripts/package/merge_binary_info_config.py"
PKG_OUTPUT_DIR="build/_CPack_Packages/makeself_staging"
RUN_PACKAGE_SAVE_AB_PATH=${TOP_DIR}/${RUN_PKG_SAVE_PATH}
ARCHIVE_RUN_DIR="${TOP_DIR}/vendor/hisi/build/delivery/${SOC}/"
MERGE_OPS_SCRIPT="$TOP_DIR/open_source/cann-cmake/scripts/package/json_merger.py"
cd ${WORKDIR}/ || exit
ensure_dir "$TEMP_RUN_DIR"
cd "$TEMP_RUN_DIR"
log "Working in temporary directory: $(pwd)"
shopt -s globstar nullglob
kernel_run_files=("$RUN_PACKAGE_SAVE_AB_PATH"/**/cann-*custom_operator_group*.run)
shopt -u globstar nullglob
[[ ${#kernel_run_files[@]} -gt 0 ]] || \
die "No .run files found in $RUN_PACKAGE_SAVE_AB_PATH"
ensure_dir "../$MAKESELF_TARGET_DIR"
cp -rf "$TOP_DIR"/open_source/makeself/* "../$MAKESELF_TARGET_DIR" || die "Failed to copy $MAKESELF_TARGET_DIR"
cd $RUN_PACKAGE_SAVE_AB_PATH
host_file_name=$(find . -type f -name "*.run" | grep -v "custom")
host_file_name="${host_file_name#./}"
cd "${WORKDIR}"
cd "${TEMP_RUN_DIR}"
host_run_src="$RUN_PACKAGE_SAVE_AB_PATH/$host_file_name"
if [ -e $host_run_src ]; then
cp -v $host_run_src "./$HOST_RUN_NAME" || die "Failed to copy host run file"
log "Copied host run file: $host_run_src -> $HOST_RUN_NAME"
else
log "Host run file not found: $host_run_src"
fi
if [[ ! -x "./$HOST_RUN_NAME" ]]; then
chmod +x "./$HOST_RUN_NAME" || die "Cannot make $HOST_RUN_NAME executable"
fi
log "Extracting $HOST_RUN_NAME to ./$HOST_EXTRACT_DIR"
"./$HOST_RUN_NAME" --extract="$HOST_EXTRACT_DIR" --noexec || \
die "Failed to extract $HOST_RUN_NAME"
rm -f "./$HOST_RUN_NAME"
log "Removed $HOST_RUN_NAME after extraction"
ensure_dir "./$HOST_EXTRACT_DIR"
PARALLEL_EXTRACT_NUM=${PARALLEL_EXTRACT_NUM:-16}
PROCESS_FIFO="/tmp/process_fifo_$$"
PROCESS_ERROR_FILE="/tmp/process_errors_$$"
> "$PROCESS_ERROR_FILE"
TARGET_KERNEL_DIR="$HOST_EXTRACT_DIR/${OPP_PREFIX}/built-in/op_impl/ai_core/tbe/kernel/$SOC/$PKG_NAME/"
TARGET_CONFIG_DIR="$HOST_EXTRACT_DIR/${OPP_PREFIX}/built-in/op_impl/ai_core/tbe/kernel/config/$SOC/ops_transformer"
ensure_dir "$TARGET_KERNEL_DIR"
ensure_dir "$TARGET_CONFIG_DIR"
if [[ ${#kernel_run_files[@]} -gt 0 ]]; then
[ -e "$PROCESS_FIFO" ] || mkfifo "$PROCESS_FIFO"
exec 8<>"$PROCESS_FIFO"
rm -f "$PROCESS_FIFO"
for ((i=1;i<=PARALLEL_EXTRACT_NUM;i++)); do echo >&8; done
for runfile in "${kernel_run_files[@]}"; do
read -u8
{
if [[ ! -x "$runfile" ]]; then
chmod +x "$runfile"
fi
parent_dir=$(basename "$(dirname "$runfile")")
runfile_basename=$(basename "$runfile" .run)
base_name="kernel_${parent_dir}_${runfile_basename}"
extract_dir="./$base_name"
log "Extracting and processing $runfile"
"$runfile" --extract="$extract_dir" --noexec || {
echo "$runfile: extract failed" >> "$PROCESS_ERROR_FILE"
echo >&8
exit 1
}
full_path=$(find "${extract_dir}/packages/vendors" -maxdepth 1 -type d -name "custom_*_transformer" 2>/dev/null | head -n 1)
if [[ -z "$full_path" ]]; then
echo "$runfile: kernel_dir not found" >> "$PROCESS_ERROR_FILE"
echo >&8
exit 1
fi
kernel_dir_name=$(basename "$full_path")
kernel_src_dir="$extract_dir/packages/vendors/$kernel_dir_name/op_impl/ai_core/tbe/kernel/${SOC}"
config_src_dir="$extract_dir/packages/vendors/$kernel_dir_name/op_impl/ai_core/tbe/kernel/config/${SOC}"
[[ -d "$kernel_src_dir" && -d "$config_src_dir" ]] || { echo >&8; exit 0; }
for json_file in "$config_src_dir"/*.json; do
[[ -f "$json_file" ]] || continue
json_name=$(basename "$json_file" .json)
cp "$json_file" "$TARGET_CONFIG_DIR/${json_name}_${base_name}.json"
done
rsync -au "$kernel_src_dir/" "$TARGET_KERNEL_DIR/" 2>> "$PROCESS_ERROR_FILE"
echo >&8
exit 0
}&
done
wait
exec 8>&-
if [[ -s "$PROCESS_ERROR_FILE" ]]; then
log "Errors during parallel processing:"
cat "$PROCESS_ERROR_FILE"
rm -f "$PROCESS_ERROR_FILE"
die "Parallel processing failed"
fi
rm -f "$PROCESS_ERROR_FILE"
fi
merge_all_jsons() {
local binary_script="$1" ops_script="$2"
declare -A groups
log "Merging JSON files..."
for f in "$TARGET_CONFIG_DIR"/*_*.json; do
[[ -f "$f" ]] || continue
name=$(basename "$f" .json)
base="${name%_kernel_*}"
[[ "$base" == "$name" ]] && continue
groups[$base]+="$f "
done
for base in "${!groups[@]}"; do
read -ra files <<< "${groups[$base]}"
n=${#files[@]}
[[ $n -eq 1 ]] && { mv "${files[0]}" "${TARGET_CONFIG_DIR}/${base}.json"; continue; }
script="$ops_script"; priority="last"
[[ "$base" =~ ^(binary_info_config|relocatable_kernel_info_config)$ ]] && { script="$binary_script"; priority="first"; }
log " $base: $n files"
python3 "$script" --input-files "${files[@]}" --output-file "${TARGET_CONFIG_DIR}/${base}.json" --priority "$priority"
rm -f "${files[@]}"
done
}
merge_all_jsons "$MERGE_SCRIPT" "$MERGE_OPS_SCRIPT"
for runfile in "${kernel_run_files[@]}"; do
[[ -f "$runfile" ]] || continue
parent_dir=$(basename "$(dirname "$runfile")")
runfile_basename=$(basename "$runfile" .run)
base_name="kernel_${parent_dir}_${runfile_basename}"
extract_dir="./$base_name"
if [[ -d "$extract_dir" ]]; then
rm -rf "$extract_dir"
fi
done
filelist_src_path="$HOST_EXTRACT_DIR/share/info/ops_transformer/script/filelist.csv"
rm -f "$filelist_src_path"
ensure_dir "../$RUNFILE_TARGET_DIR"
cp -rf "$HOST_EXTRACT_DIR"/* "../$RUNFILE_TARGET_DIR"/ || \
die "Failed to copy host content to makeself directory"
log "Host content copied to $RUNFILE_TARGET_DIR"
cd "../" || echo "Failed to go back to workdir"
log "Executing package.py to generate final package..."
python3 "$PACKAGE_SCRIPT" \
--pkg_name "$PKG_NAME" \
--makeself_dir "${WORKDIR}/$MAKESELF_TARGET_DIR" \
--pkg-output-dir "${WORKDIR}/$PKG_OUTPUT_DIR" \
--independent_pkg \
--chip_name "$SOC" \
--os_arch linux-"$OS_ARCH"\
--delivery_dir "${WORKDIR}/build" \
--source_dir "${WORKDIR}"
log "Packaging completed successfully!"
ensure_dir "$ARCHIVE_RUN_DIR"
cp -r "$PKG_OUTPUT_DIR"/*.run $ARCHIVE_RUN_DIR