#!/usr/bin/bash
#version 23100100
#nvidia-driver2G,CUDA4G,8G CUDNN 12G
#pip1G,pyTorch3G,Paddle3G,Tensorflow3G, 1+3*3
#conda2G,condaPaddle4G*3,2+4*4
#docker2G,3+5*3
#版本2,
#
#todo 
#apt lock导致无法apt安装
#cudnn、TensorRT、AVX2、AVX_VNNI、FMA
#conda TensorFlow

#CLI
#启动授权方式
#换成国内源
#检测用户IP，根据ip地址提供下载方式

#cuDNN
#docker
#docker-nvidia
#输出信息有乱码，

#terminal stable CLI
#阻止系统休眠

trap 'TaskTerm; exit' SIGTERM
trap 'TaskInt; exit' SIGINT
#trap 'TaskUP; exit' SIGUP


function version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" == "$1"; }
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }


# cur_py="python3.12"
# py_ver="3.12"
# cur_pip="pipx"

cur_py="python3.11"
py_ver="3.11"
cur_pip="pip"

if version_lt $version 2.0
then
    echo "system version is less than 2.0"
	cur_py="python3.8"
	py_ver="3.8"
	cur_pip="pip"
	update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
else
	update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1
fi

function TaskTerm()
{
 	echo "TaskTerm is done"
}
function TaskInt()
{
	echo "TaskInt is done"
}
function TaskUP()
{
 	echo "TaskUP is done"
}

sigProgStart="ProgFreeStart"
sigProgEnd="ProgFreeEnd"
cachePath=~/.aiassistant
tmpPath=~/.aiassistant/tmp
pathAdd=()
ldPathAdd=()
stepIndex=1
stepNum=2
exitCode=0
isPreVersion=0

#解析命令参数
# getopts
while getopts ":h:u:f:v:p:c:d" opt
do
case $opt in
	h)
		home=$OPTARG
		# echo "Home Directory is $home"
		;;
	u)
		user=$OPTARG
		# echo "USER is $user"
		;;
	f)
		framework=$OPTARG
		# echo "framework is $framework"
		;;
	v)
		version=$OPTARG
		isPreVersion=1
		echo "version is $version"
		;;
	p)
		package=$OPTARG
		case $package in
		pip)  
			stepNum=$[stepNum+3]
		;;
		conda)  
			stepNum=$[stepNum+5]
		;;
		docker)  
			stepNum=$[stepNum+1]
		;;
		*)  
			:
		;;
		esac
		# if [ "$package" == "pip" ]
		# then
		# 	stepNum=$[stepNum+1]
		# elif [ "$package" == "conda" ]
		# then
		# 	stepNum=$[stepNum+3]
		# elif [ "$package" == "docker" ]
		# then
		# 	stepNum=$[stepNum+2]
		# fi
		# echo "package is $package"
		;;
	c)
		cuda=$OPTARG
		# echo "computer platform is $cuda"
		if [ "$cuda" == "ANY" ]
		then
			cuda="11.8"
		fi
		if [[ "$cuda" != "CPU" ]]
		then
			stepNum=$[stepNum+5] 
		fi
		#init:1 nvidia:1 cuda:2 cudnn:2 
		#prepython:1 prepip:1 updatepip:1
		# conda:2 
		#docker: install:1
		# echo "new computer platform is $cuda"
		;;
	d)
		debug=$OPTARG
		# echo "debug is set"
		;;
	?)
		# echo "get param error"
		exit 1;;
esac
done

#更新系统环境变量
function updateEnv()
{

	# isExist=false
	# echo $PATH
	# for str in $pathAdd; 
	# do
	# 	echo $str
        # if [[ $PATH =~ $str ]]
		# then
		# isExist=true
		# echo "is Exist in PATH"
	# 	break
	# 	fi
	# done

	# if [ !isExist ]
	# then
	# 	echo "is not Exist in PATH"	
	# 	pathAdd[${#array_name[@]}]="/usr/local/cuda-11.8/bin"
	# fi	
	# echo $pathAdd

	# for str in $pathAdd; 
	# do
	# 	echo $str
    #     if [[ $PATH =~ $str ]]
	# 	then
	# 	isExist=true
	# 	echo "is Exist in PATH Now"
	# 	break
	# 	fi
	# done

	#已经支持不覆盖以前，也不重复添加
	#todo 不用重启有效，
	echo "update system environment variables..."
	# pathAdd[${#pathAdd[@]}]="/usr/local/cuda-11.8/bin"
	# ldPathAdd[${#ldPathAdd[@]}]="/usr/local/cuda-11.8/lib64"
	#/etc/profile.d/aiasst-env.sh
	if [ ! -f $home/.bashrc ]
	then
		printf "" > $home/.bashrc
	fi
	for str in ${pathAdd[@]}
	do
		if [[ $PATH =~ $str ]]
		then
			:
		else
			export PATH=$str:$PATH
		fi
		if grep "export PATH=$str:" $home/.bashrc > /dev/null 
		then
			:
		else
			echo export PATH=$str:'$PATH' >> $home/.bashrc
		fi
	done
	for str in ${ldPathAdd[@]}
	do
		if [[ $PATH =~ $str ]]
		then
			:
		else
			export PATH=$str:$PATH
		fi
		if grep "export LD_LIBRARY_PATH=$str:" $home/.bashrc > /dev/null
		then
			:
		else
			echo export LD_LIBRARY_PATH=$str:'$LD_LIBRARY_PATH' >> $home/.bashrc
		fi
	done
}



#检查是否存在英伟达显卡
function checkExistNvidiaCard()
{
	# echo "Check exist nvidia card"
	lspci | grep -i nvidia
}

#安装显卡驱动
function installNvidiaDriver()
{
	stepIndex=$[stepIndex+1]
	echo "progIV:$sigProgStart" >& 2
	echo "progIV: step$stepIndex/$stepNum installing nvidia driver..." >& 2
	#method 1
	echo "installing nvidia-driver-535..."
	#noInstall=$(apt list --installed 2> /dev/null | grep nvidia-driver-535)
	#cp /etc/apt/sources.list /etc/apt/sources.list.xxbk ## && echo "Successfully backup sources.list"
	#echo $shouldInstall
	if apt list --installed 2> /dev/null | grep nvidia-driver-535
	then
		nvidia-smi | grep 'NVIDIA-SMI has failed' > /dev/null && exitCode=66
	else
		apt install -y nvidia-driver-535 2> /dev/null && echo "install nvidia-driver-535 successfully, need reboot computer later" && exitCode=66
	fi
	#cp /etc/apt/sources.list.xxbk /etc/apt/sources.list ## && echo "Successfully resotre sources.list"

	#method 2
	#/usr/share/aiasst
	# bash -c "echo 'blacklist nouveau' > /etc/modprobe.d/nouveau.conf"
	# sudo update-initramfs -u
	# ##/lib/systemd/system/rc-local.service
	# sudo cp /media/lhh/work/QuickInstallAI/rc-local.service /etc/systemd/system/rc-local.service
	# #chmod +x
	# cp /media/lhh/work/QuickInstallAI/rc.local /etc/rc.local
	# systemctl set-default multi-user.target
	# reboot
	echo "progIV:$sigProgEnd" >& 2
}

#检查CUDA是否已经安装
function checkCUDA()
{
	if [ -d /usr/local/cuda-$cuda/lib64 ]
	then
		return 0
	else
		return 1
	fi
}

#安装CUDA12.1
function installCUDA121()
{
	#method2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum downloading resources of CUDA$cuda..." >& 2
	echo "downloading resources of CUDA$cuda..."
	
	let sizeorig=4317456991
	md5orig="2f0a4127bf797bf4eab0be2a547cb8d0"
	while true
	do
	if [ ! -f cuda_12.1.1_530.30.02_linux.run ]
	then
		wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_12.1.1_530.30.02_linux.run -O cuda_12.1.1_530.30.02_linux.run >& 2 && echo "Successfully download cuda_12.1.1_530.30.02_linux.run"
	else
		let fileSize=$(du -b cuda_12.1.1_530.30.02_linux.run | grep -E -o [0-9]+ | head -n 1)
		if [ $fileSize -lt $sizeorig ]
		then
			wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_12.1.1_530.30.02_linux.run -O cuda_12.1.1_530.30.02_linux.run >& 2 && echo "Successfully download cuda_12.1.1_530.30.02_linux.run"
		elif [ $fileSize -eq $sizeorig ]
		then
			echo "progIV:$sigProgStart" >& 2
			echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
			echo "verify file integrity..."	
			result=$(md5sum cuda_12.1.1_530.30.02_linux.run)
			compare=$(echo $result | grep $md5orig)
			if [[ "$compare" != "" ]]
			then
				echo "verify file integrity...yes"	
				break
			else
				echo "verify file integrity...failed"	
				rm cuda_12.1.1_530.30.02_linux.run && echo "Remove corrupted file cuda_12.1.1_530.30.02_linux.run"
			fi
			echo "progIV:$sigProgEnd" >& 2
		else
			rm cuda_12.1.1_530.30.02_linux.run && echo "Remove corrupted file cuda_12.1.1_530.30.02_linux.run"
		fi
	fi
	done
	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing $cuda..." >& 2
	echo "installing CUDA$cuda..."
	
	sh cuda_12.1.1_530.30.02_linux.run --silent --toolkit --tmpdir=$tmpPath && echo "Successfully install CUDA$cuda"
	echo "progIV:$sigProgEnd" >& 2
}

#安装CUDA12.0
function installCUDA120()
{
	#method2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum downloading resources of CUDA$cuda..." >& 2
	echo "downloading resources of CUDA$cuda..."

	let sizeorig=4207617207
	md5orig="2a5b80f322151e25ed792029e4571318"
	while true
	do
	if [ ! -f cuda_12.0.1_525.85.12_linux.run ]
	then
		wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_12.0.1_525.85.12_linux.run -O cuda_12.0.1_525.85.12_linux.run >& 2 && echo "Successfully download cuda_12.0.1_525.85.12_linux.run"
	else
		let fileSize=$(du -b cuda_12.0.1_525.85.12_linux.run | grep -E -o [0-9]+ | head -n 1)
		if [ $fileSize -lt $sizeorig ]
		then
			wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_12.0.1_525.85.12_linux.run -O cuda_12.0.1_525.85.12_linux.run >& 2 && echo "Successfully download cuda_12.0.1_525.85.12_linux.run"
		elif [ $fileSize -eq $sizeorig ]
		then
			echo "progIV:$sigProgStart" >& 2
			echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
			echo "verify file integrity..."	
			result=$(md5sum cuda_12.0.1_525.85.12_linux.run)
			compare=$(echo $result | grep $md5orig)
			if [[ "$compare" != "" ]]
			then
				echo "verify file integrity...yes"	
				break
			else
				echo "verify file integrity...failed"	
				rm cuda_12.0.1_525.85.12_linux.run && echo "Remove corrupted file cuda_12.0.1_525.85.12_linux.run"
			fi
			echo "progIV:$sigProgEnd" >& 2
		else
			rm cuda_12.0.1_525.85.12_linux.run && echo "Remove corrupted file cuda_12.0.1_525.85.12_linux.run"
		fi
	fi
	done
	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing $cuda..." >& 2
	echo "installing CUDA$cuda..."
	
	sh cuda_12.0.1_525.85.12_linux.run --silent --toolkit --tmpdir=$tmpPath && echo "Successfully install CUDA$cuda"
	echo "progIV:$sigProgEnd" >& 2
}

#安装CUDA11.8
function installCUDA118()
{
	#method2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum downloading resources of CUDA$cuda..." >& 2
	echo "downloading resources of CUDA$cuda..."
	
	let sizeorig=4336730777
	md5orig="d6cf26349e5a4104b8683e26b717fa22"
	while true
	do
	if [ ! -f cuda_11.8.0_520.61.05_linux.run ]
	then
		wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_11.8.0_520.61.05_linux.run -O cuda_11.8.0_520.61.05_linux.run >& 2 && echo "Successfully download cuda_11.8.0_520.61.05_linux.run"
	else
		let fileSize=$(du -b cuda_11.8.0_520.61.05_linux.run | grep -E -o [0-9]+ | head -n 1)
		if [ $fileSize -lt $sizeorig ]
		then
			wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_11.8.0_520.61.05_linux.run -O cuda_11.8.0_520.61.05_linux.run >& 2 && echo "Successfully download cuda_11.8.0_520.61.05_linux.run"
		elif [ $fileSize -eq $sizeorig ]
		then
			echo "progIV:$sigProgStart" >& 2
			echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
			echo "verify file integrity..."	
			result=$(md5sum cuda_11.8.0_520.61.05_linux.run)
			compare=$(echo $result | grep $md5orig)
			if [[ "$compare" != "" ]]
			then
				echo "verify file integrity...yes"	
				break
			else
				echo "verify file integrity...failed"	
				rm cuda_11.8.0_520.61.05_linux.run && echo "Remove corrupted file cuda_11.8.0_520.61.05_linux.run"
			fi
			echo "progIV:$sigProgEnd" >& 2
		else
			rm cuda_11.8.0_520.61.05_linux.run && echo "Remove corrupted file cuda_11.8.0_520.61.05_linux.run"
		fi
	fi
	done
	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing $cuda..." >& 2
	echo "installing CUDA$cuda..."
	
	sh cuda_11.8.0_520.61.05_linux.run --silent --toolkit --tmpdir=$tmpPath && echo "Successfully install CUDA$cuda"
	echo "progIV:$sigProgEnd" >& 2
	
}

#安装CUDA11.7
function installCUDA117()
{
	#method 1
	# if [ ! -f cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb ]
	# then
	# 	wget -c https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb
	# else
	# 	echo "use cached cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb"
	# fi
	# dpkg -i cuda-repo-ubuntu2204-11-7-local_11.7.1-515.65.01-1_amd64.deb
	# cp /var/cuda-repo-ubuntu2204-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/
	# apt-get update &> /dev/null
	# apt-get -y install cuda && echo "Successfully install CUDA11.7"

	#method2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum downloading resources of CUDA$cuda..." >& 2
	echo "downloading resources of CUDA$cuda..."

	let sizeorig=3524358811
	md5orig="cd470869c316fb7f389b3fdf34edec5f"
	while true
	do
	if [ ! -f cuda_11.7.1_515.65.01_linux.run ]
	then
		wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_11.7.1_515.65.01_linux.run -O cuda_11.7.1_515.65.01_linux.run >& 2 && echo "Successfully download cuda_11.7.1_515.65.01_linux.run"
	else
		let fileSize=$(du -b cuda_11.7.1_515.65.01_linux.run | grep -E -o [0-9]+ | head -n 1)
		if [ $fileSize -lt $sizeorig ]
		then
			wget -c https://archive.openkylin.top/openkylin/dep-file/cuda4/cuda_11.7.1_515.65.01_linux.run -O cuda_11.7.1_515.65.01_linux.run >& 2 && echo "Successfully download cuda_11.7.1_515.65.01_linux.run"
		elif [ $fileSize -eq $sizeorig ]
		then
			echo "progIV:$sigProgStart" >& 2
			echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
			echo "verify file integrity..."	
			result=$(md5sum cuda_11.7.1_515.65.01_linux.run)
			compare=$(echo $result | grep $md5orig)
			if [[ "$compare" != "" ]]
			then
				echo "verify file integrity...yes"	
				break
			else
				echo "verify file integrity...failed"	
				rm cuda_11.7.1_515.65.01_linux.run && echo "Remove corrupted file cuda_11.7.1_515.65.01_linux.run"
			fi
			echo "progIV:$sigProgEnd" >& 2
		else
			rm cuda_11.7.1_515.65.01_linux.run && echo "Remove corrupted file cuda_11.7.1_515.65.01_linux.run"
		fi
	fi
	done
	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing $cuda..." >& 2
	echo "installing CUDA$cuda..."
	
	sh cuda_11.7.1_515.65.01_linux.run --silent --toolkit --tmpdir=$tmpPath && echo "Successfully install CUDA$cuda"
	echo "progIV:$sigProgEnd" >& 2
}


#安装CUDA
function installCUDA()
{
	cd $cachePath

	case $cuda in
	12.1)  
		installCUDA121
    ;;
    12.0)  
		installCUDA120
    ;;
    11.8)  
		installCUDA118
    ;;
    11.7)  
		installCUDA117
    ;;
    *)  
		echo "CUDA Version Error"
    ;;
	esac
}

#检查CUDNN是否已经安装
function checkCUDNN()
{
	if [ -f /usr/local/cuda/lib64/libcudnn.so ]
	then
		return 0
	else
		return 1
	fi
}

#安装CUDNN11
function installCUDNN11()
{
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing cudnn-local-repo..." >& 2
	#echo "downloading resources of cuDNN..."
	echo "installing cudnn-local-repo..."
	echo "progIV:$sigProgStart" >& 2

	# let sizeorig=874642234
	# md5orig="55bbfe65b56cab3f82aed79bed559a59"
	# while true
	# do
	# if [ ! -f 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb ]
	# then
	# 	wget -c http://38.47.255.174/cudnn/11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb -O 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb >& 2 && echo "Successfully download 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# else
	# 	let fileSize=$(du -b 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb | grep -E -o [0-9]+ | head -n 1)
	# 	if [ $fileSize -lt $sizeorig ]
	# 	then
	# 		wget -c http://38.47.255.174/cudnn/11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb -O 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb >& 2 && echo "Successfully download 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 	elif [ $fileSize -eq $sizeorig ]
	# 	then
	# 		echo "progIV:$sigProgStart" >& 2
	# 		echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
	# 		echo "verify file integrity..."	
	# 		result=$(md5sum 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb)
	# 		compare=$(echo $result | grep $md5orig)
	# 		if [[ "$compare" != "" ]]
	# 		then
	# 			echo "verify file integrity...yes"	
	# 			break
	# 		else
	# 			echo "verify file integrity...failed"	
	# 			rm 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb && echo "Remove corrupted file 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 		fi
	# 		echo "progIV:$sigProgEnd" >& 2
	# 	else
	# 		rm 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb && echo "Remove corrupted file 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 	fi
	# fi
	# done
	
	apt install -y 11cudnn-local-repo-ubuntu2204-8.9.5.29 2> /dev/null && "Successfully install 11cudnn-local-repo..."
	# dpkg -i 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb
	echo "progIV:$sigProgEnd" >& 2

	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing cuDNN..." >& 2

	cp /var/cudnn-local-repo-ubuntu2204-8.9.5.29/cudnn-local-535C49CB-keyring.gpg /usr/share/keyrings/
	echo "apt udapte..."
	apt update 2> /dev/null && echo "apt udapted"

	echo "installing cuDNN..."
	
	# dpkg -i 11cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb
	
	apt install -y libcudnn8-dev 2> /dev/null && "Successfully install libcudnn8-dev..."
	echo "progIV:$sigProgEnd" >& 2
}

#安装CUDNN12
function installCUDNN12()
{
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing cudnn-local-repo..." >& 2
	#echo "downloading resources of cuDNN..."
	echo "installing cudnn-local-repo..."
	echo "progIV:$sigProgStart" >& 2
	# let sizeorig=878994438
	# md5orig="732c26ee4ae56b008722ac8a47ac95d6"
	# while true
	# do
	# if [ ! -f 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb ]
	# then
	# 	wget -c http://38.47.255.174/cudnn/12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb -O 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb >& 2 && echo "Successfully download 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# else
	# 	let fileSize=$(du -b 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb | grep -E -o [0-9]+ | head -n 1)
	# 	if [ $fileSize -lt $sizeorig ]
	# 	then
	# 		wget -c http://38.47.255.174/cudnn/12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb -O 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb >& 2 && echo "Successfully download 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 	elif [ $fileSize -eq $sizeorig ]
	# 	then
	# 		echo "progIV:$sigProgStart" >& 2
	# 		echo "progIV: step$stepIndex/$stepNum verify file integrity..." >& 2
	# 		echo "verify file integrity..."	
	# 		result=$(md5sum 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb)
	# 		compare=$(echo $result | grep $md5orig)
	# 		if [[ "$compare" != "" ]]
	# 		then
	# 			echo "verify file integrity...yes"	
	# 			break
	# 		else
	# 			echo "verify file integrity...failed"	
	# 			rm 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb && echo "Remove corrupted file 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 		fi
	# 		echo "progIV:$sigProgEnd" >& 2
	# 	else
	# 		rm 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb && echo "Remove corrupted file 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb"
	# 	fi
	# fi
	# done
	apt install -y 12cudnn-local-repo-ubuntu2204-8.9.5.29 2> /dev/null && "Successfully install 12cudnn-local-repo..."

	echo "progIV:$sigProgEnd" >& 2

	echo "progIV:$sigProgStart" >& 2
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum installing cuDNN..." >& 2
	cp /var/cudnn-local-repo-ubuntu2204-8.9.5.29/cudnn-local-275FA572-keyring.gpg /usr/share/keyrings/
	echo "apt udapte..."
	apt update 2> /dev/null && echo "apt udapted"

	echo "installing cuDNN..."
	
	# dpkg -i 12cudnn-local-repo-ubuntu2204-8.9.5.29_1.0-1_amd64.deb
	apt install -y libcudnn8-dev 2> /dev/null && "Successfully install libcudnn8-dev..."
	echo "progIV:$sigProgEnd" >& 2
}

#根据CUDA版本安装CUDNN
function installCUDNN()
{
	cd $cachePath
	case $cuda in
	12.1)  
		installCUDNN12
    ;;
    12.0)  
		installCUDNN12
    ;;
    11.8)  
		installCUDNN11
    ;;
    11.7)  
		installCUDNN11
    ;;
    *)  
		echo "CUDA Version Error"
    ;;
	esac
}



#测试进度条输出功能
function testProgress()
{
	echo "test progress"
	# echo "progIV:$sigProgStart" >& 2
	# echo "progIV: step$stepIndex/$stepNum init..." >& 2
	# progV=1
	# until [ $progV = 100 ]
	# do
	# 	progV=$[progV+1]
	# 	sleep 1
	# done
	

	# echo "progIV:$sigProgEnd" >& 2

	# progV=1
	# until [ $progV = 100 ]
	# do
	# 	echo "progIV: $progV/100" >&2
	# 	echo "progIV:=$progV" >&2
	# 	progV=$[progV+1]
	# 	sleep 1
	# done

	# wget http://38.47.255.174/kylin-photo-viewer.zip >& 2
	
}

#安装前准备
function init()
{
	##	>& 2 输出到stderr
	##	2> /dev/null 没有错误输出
	echo "progIV:$sigProgStart" >& 2
	echo "progIV: step$stepIndex/$stepNum init..." >& 2
	echo "init..."
	mkdir -p $cachePath
	mkdir -p $tmpPath
	echo -e "deb http://archive.build.openkylin.top/openkylin/ yangtze main cross pty\ndeb http://archive.build.openkylin.top/openkylin/ yangtze-security main cross pty\ndeb http://archive.build.openkylin.top/openkylin/ yangtze-updates main cross pty\ndeb http://archive.build.openkylin.top/openkylin/ yangtze-proposed main cross pty" > /etc/apt/sources.list ## && echo "Successfully change sources.list"
	echo "progIV: step$stepIndex/$stepNum apt update..." >& 2
	
	echo "apt update..."
	apt update 2> /dev/null
	echo "progIV:$sigProgEnd" >& 2
}

#准备Python相关环境
function prePythonEnv()
{
	stepIndex=$[stepIndex+1]
	echo "progIV:$sigProgStart" >& 2
	echo "progIV: step$stepIndex/$stepNum prepare python environment..." >& 2
	echo "prepare python environment..."
	if apt list --installed 2> /dev/null | grep $cur_py
	then
		:
	else
		apt install -y $cur_py 2> /dev/null && echo "Successfully install python3"
	fi

	# if apt list --installed 2> /dev/null | grep python-is-python3
	# then
	# 	:
	# else
	# 	apt install -y python-is-python3 2> /dev/null && echo "Successfully python-is-python3"
	# fi
	echo "progIV:$sigProgEnd" >& 2
}

#准备pip相关环境
function prePipEnv()
{
	local time=1
	stepIndex=$[stepIndex+1]
	
	echo "progIV: step$stepIndex/$stepNum prepare $package environment..." >& 2
	echo "prepare $package environment..."
	echo "progIV:$sigProgStart" >& 2
	if apt list --installed 2> /dev/null | grep python3-pip
	then
		:
	else
		apt install -y python3-pip 2> /dev/null && echo "Successfully install python3-pip"
	fi

	if version_gt $version 2.0
	then
		if apt list --installed 2> /dev/null | grep pipx
		then
			:
		else
			apt install -y pipx 2> /dev/null && echo "Successfully install pipx"
		fi
		cur_pip ensurepath
	fi

	#apt install -y python3-dev python3-pip python3-venv
	# su $user
	echo "progIV:$sigProgEnd" >& 2
	if [ -f /usr/bin/kwalletd5 ]
	then
		mv /usr/bin/kwalletd5 /usr/bin/kwalletd5_bak
	fi

	pathAdd[${#pathAdd[@]}]="$home/.local/bin"
	updateEnv
}

#准备Docker相关环境
function preDockerEnv()
{
	stepIndex=$[stepIndex+1]
	echo "progIV: step$stepIndex/$stepNum prepare $package environment..." >& 2
	echo "prepare $package environment..."
	# echo "progIV:$sigProgStart" >& 2

	
	#apt install -y python3-dev python3-pip python3-venv
	# su $user
	
	usermod -aG kvm $user
	groupadd docker
	gpasswd -a $user docker

	
	if [[ "$cuda" != "CPU" ]]
	then
		curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list && apt update
		apt install -y nvidia-container-toolkit && echo "Successfully install nvidia-container-toolkit" && nvidia-ctk runtime configure --runtime=docker && systemctl restart docker
	 fi

	echo "progIV:$sigProgEnd" >& 2



	# Add Docker's official GPG key:
# 	apt update
# 	apt install -y ca-certificates curl gnupg
# 	install -m 0755 -d /etc/apt/keyrings
# 	curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o -f /etc/apt/keyrings/docker.gpg
# 	chmod a+r /etc/apt/keyrings/docker.gpg

# # Add the repository to Apt sources:
# 	echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
#  	apt update


	# if [[ "$cuda" != "CPU" ]]
	# then
	# 	# 添加Nvidia-Docker的GPG key
	# 	curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
	
	# 	# 添加Nvidia-Docker的repository
	# 	distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
	# 	curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | tee /etc/apt/sources.list.d/nvidia-docker.list
		
	# 	# 更新apt-get
	# 	# sudo apt-get update
		
	# 	# 安装Nvidia-Docker
	# 	# 方法一：
	# 	# 安装Nvidia-Docker, Nvidia-Docker有两个版本，版本2为新版，此处安装的为版本2
	# 	# sudo apt-get install -y nvidia-docker2 && echo "Successfully install nvidia-docker2"
	# 	/
	# 	# 方法二：
	# 	# 或者直接安装nvidia-container-toolkit，nvidia-container-toolkit是一组软件包,
	# 	# 它们包括一个容器运行时库和一些工具，可以自动配置容器来利用NVIDIA GPU。
	# 	# 它支持不同的容器引擎，如Docker、containerd、LXC、Podman等。(推荐)
	# 	if apt list --installed 2> /dev/null | grep nvidia-container-toolkit
	# 	then
	# 		:
	# 	else
	# 		apt install -y nvidia-container-toolkit 2> /dev/null && echo "Successfully nvidia-container-toolkit"
	# 	fi
		
		
	# 	# docker服务重新启动
	# 	sudo systemctl restart docker
	# 	systemctl --user enable docker-desktop
	# else
	# 	if apt list --installed 2> /dev/null | grep docker/
	# 	then
	# 		:
	# 	else
	# 		apt install -y docker 2> /dev/null && echo "Successfully install docker"
	# 	fi
	# fi
	# echo "progIV:$sigProgEnd" >& 2
}

#程序入口，执行前准备，检查显卡，安装显卡驱动、CUDA、CUDNN，更新环境变量，准备相关环境，
function main()
{
	init
	
	if [[ "$cuda" != "CPU" ]]
	then
		if checkExistNvidiaCard
		then
			echo "check Nvidia Card... yes"
			installNvidiaDriver
		else
			echo "check Nvidia Card... no"
		fi

		if checkCUDA
		then
			stepIndex=$[stepIndex+2]
			echo "check CUDA$cuda installed... yes"
			rm /usr/local/cuda
			ln -s /usr/local/cuda-$cuda/ /usr/local/cuda
		else
			echo "check CUDA$cuda... no"
			installCUDA
		fi
		pathAdd[${#pathAdd[@]}]="/usr/local/cuda/bin"
		ldPathAdd[${#ldPathAdd[@]}]="/usr/local/cuda/lib64"
		updateEnv

		if checkCUDNN
		then
			stepIndex=$[stepIndex+2]
			echo "check cuDNN installed... yes"
		else
			echo "check cuDNN... no"
			installCUDNN
		fi
	fi

	case $package in
	pip)  
		prePythonEnv #step+1
		prePipEnv  #step+1
    ;;
    conda)  
		prePythonEnv #step+1
		prePipEnv  #step+1
    ;;
    docker)  
		preDockerEnv #step+1
    ;;
	*)  
		:
    ;;
	esac

	return $exitCode
}

main



