Skip to content

Commit 97ed23a

Browse files
committed
version 0.2.6
1 parent e480eed commit 97ed23a

File tree

20 files changed

+459
-109
lines changed

20 files changed

+459
-109
lines changed

.dev-scripts/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ To publish a binary release with docker (for CUDA), run (replace engine version
44
```bash
55
./.dev-scripts/publish-with-docker.sh v0.2.3 11.8
66
```
7+
8+
## Fixing RPaths
9+
10+
See [this github issue](https://github.com/pytorch/builder/issues/468).

.dev-scripts/basic_tests.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
# bash code to run after installation to test for correct package installation
3+
4+
if [ -n "${SKIP_TESTS}" ]; then
5+
echo "Skipping tests. Done."
6+
exit 0
7+
fi
8+
9+
# try basic importing, should detect errors of .so loading
10+
python -c "from bitorch_engine.layers.qlinear.binary.cpp import BinaryLinearCPP"
11+
python -c "from bitorch_engine.layers.qembedding.binary import BinaryEmbeddingCuda"
12+
python -c "from bitorch_engine.layers.qlinear.nbit.cutlass import Q4LinearCutlass, Q8LinearCutlass, Q4MatMul"
13+
python -c "from bitorch_engine.layers.qlinear.nbit.cuda import MPQLinearCuda, MBWQLinearCuda"
14+
python -c "from bitorch_engine.layers.qlinear.nbit.cuda.utils import pack_fp_weight, unpack_qweight"
15+
echo "Imports successful!"
16+
17+
set +o errexit
18+
echo "Testing..."
19+
(
20+
rm -rf bitorch_install_tmp_test_dir
21+
mkdir bitorch_install_tmp_test_dir
22+
cd bitorch_install_tmp_test_dir
23+
git clone https://github.com/GreenBitAI/bitorch-engine.git --depth 1 --branch "v0.2.5" bitorch_engine_git
24+
mv bitorch_engine_git/tests .
25+
pip install pytest numpy
26+
pytest tests/layers/test_nbit_linear.py
27+
pytest tests/layers/test_nbit_linear_mixbits.py
28+
pytest tests/functions/test_quant_ops.py
29+
pytest tests/layers/test_binary_linear.py
30+
)
31+
rm -rf bitorch_install_tmp_test_dir

.dev-scripts/extract_install_cmd.py

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,31 @@
55
import argparse
66
parser = argparse.ArgumentParser()
77
parser.add_argument("custom_pytorch_path", help="Path to custom PyTorch wheel")
8+
parser.add_argument("custom_bitorch_engine_path", help="Path to built bitorch engine wheel file")
89
args = parser.parse_args()
910

10-
BLOCK_HEADER_START = "#### Conda on Linux"
11+
BLOCK_HEADER_START_BINARY = "### Binary Release"
12+
BLOCK_HEADER_START_FROM_SOURCE = "#### Conda on Linux"
13+
BLOCK_END = "##########"
1114

1215
with open("README.md") as infile:
1316
content = infile.readlines()
1417

15-
local_install_instructions = []
16-
global_install_instructions = []
18+
with open(".dev-scripts/basic_tests.sh") as infile:
19+
test_appendix = infile.readlines()
20+
21+
22+
def write_file(filepath, main_content):
23+
with open(filepath, "w") as outfile:
24+
outfile.write(FILE_INTRO)
25+
outfile.writelines(main_content)
26+
outfile.writelines(test_appendix)
27+
28+
29+
source_local_install_instructions = []
30+
source_global_install_instructions = []
31+
binary_local_install_instructions = []
32+
binary_global_install_instructions = []
1733

1834
in_code_block = False
1935
reading_instructions = False
@@ -36,17 +52,29 @@
3652
if line.startswith("```"):
3753
in_code_block = not in_code_block
3854
continue
39-
if line.startswith(BLOCK_HEADER_START):
55+
if line.startswith(BLOCK_HEADER_START_FROM_SOURCE):
4056
reading_instructions = True
41-
instruction_type = "global"
57+
instruction_type = "source-global"
58+
BLOCK_END = BLOCK_HEADER_START_FROM_SOURCE.split()[0]
59+
continue
60+
if line.startswith(BLOCK_HEADER_START_BINARY):
61+
reading_instructions = True
62+
instruction_type = "binary-global"
63+
BLOCK_END = BLOCK_HEADER_START_BINARY.split()[0]
4264
continue
4365
if line.startswith("<details><summary>"):
44-
instruction_type = "local"
66+
if "source" in instruction_type:
67+
instruction_type = "source-local"
68+
if "binary" in instruction_type:
69+
instruction_type = "binary-local"
4570
continue
4671
if line.startswith("</details>"):
47-
instruction_type = "both"
72+
if "source" in instruction_type:
73+
instruction_type = "source-both"
74+
if "binary" in instruction_type:
75+
instruction_type = "binary-both"
4876
continue
49-
if line.startswith(BLOCK_HEADER_START.split()[0]):
77+
if line.startswith(BLOCK_END):
5078
reading_instructions = False
5179
continue
5280
if not reading_instructions:
@@ -68,6 +96,8 @@
6896
line = line.replace("${HOME}", "$(pwd)")
6997
if line.startswith("pip install torch-"):
7098
line = "pip install {}\n".format(args.custom_pytorch_path)
99+
if line.startswith("pip install bitorch_engine"):
100+
line = "pip install {}\n".format(args.custom_bitorch_engine_path)
71101

72102
# decide how to write line
73103
line_format = "{line}"
@@ -78,14 +108,21 @@
78108
line_format = "\n" + line_format
79109

80110
# write result line(s)
81-
if instruction_type == "global" or instruction_type == "both":
82-
global_install_instructions.append(line_format.format(line=line))
83-
if instruction_type == "local" or instruction_type == "both":
84-
local_install_instructions.append(line_format.format(line=line))
85-
86-
with open(".dev-scripts/test_local_conda_install.sh", "w") as outfile:
87-
outfile.write(FILE_INTRO)
88-
outfile.writelines(local_install_instructions)
89-
with open(".dev-scripts/test_global_conda_install.sh", "w") as outfile:
90-
outfile.write(FILE_INTRO)
91-
outfile.writelines(global_install_instructions)
111+
if instruction_type == "source-global" or instruction_type == "source-both":
112+
source_global_install_instructions.append(line_format.format(line=line))
113+
if instruction_type == "source-local" or instruction_type == "source-both":
114+
source_local_install_instructions.append(line_format.format(line=line))
115+
if instruction_type == "binary-global" or instruction_type == "binary-both":
116+
binary_global_install_instructions.append(line_format.format(line=line))
117+
if instruction_type == "binary-local" or instruction_type == "binary-both":
118+
binary_local_install_instructions.append(line_format.format(line=line))
119+
120+
write_file(".dev-scripts/test_source_local_conda_install.sh", source_local_install_instructions)
121+
write_file(".dev-scripts/test_source_global_conda_install.sh", source_global_install_instructions)
122+
write_file(".dev-scripts/test_binary_local_conda_install.sh", binary_local_install_instructions)
123+
write_file(".dev-scripts/test_binary_global_conda_install.sh", binary_global_install_instructions)
124+
125+
binary_local_cu118 = [line.replace("cu121", "cu118").replace("cuda-12.1.0", "cuda-11.8.0") for line in binary_local_install_instructions]
126+
write_file(".dev-scripts/test_binary_local_conda_install_cu118.sh", binary_local_cu118)
127+
binary_local_no_cuda = filter(lambda x: "nvidia/label/cuda-12.1.0" not in x, binary_local_install_instructions)
128+
write_file(".dev-scripts/test_binary_local_conda_install_no_cuda.sh", binary_local_no_cuda)

.dev-scripts/publish-docker-internal.sh

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,16 @@ function check_error() {
6868
fi
6969
}
7070

71+
retry () {
72+
"$@" || (sleep 2 && "$@") || (sleep 4 && "$@") || (sleep 8 && "$@")
73+
}
74+
7175
SRC_ROOT="${BITORCH_ENGINE_ROOT:-/bitorch-engine}"
7276
check_error [ -f "${SRC_ROOT}/setup.py" ]
7377
cd "${SRC_ROOT}"
7478

79+
set -o xtrace
80+
7581
# main script content
7682

7783
if [ -z "$(git status --porcelain)" ]; then
@@ -116,10 +122,141 @@ fi
116122

117123
pip install build
118124

119-
#check_error pytest .
120-
121125
check_error python3 -m build --no-isolation --wheel
122126

127+
# set patchelf binary:
128+
export PATCHELF_BIN=/usr/local/bin/patchelf
129+
patchelf_version=$($PATCHELF_BIN --version)
130+
echo "patchelf version: ${patchelf_version} (${PATCHELF_BIN})"
131+
132+
# install openssl and zip
133+
yum clean all
134+
retry yum install -q -y zip openssl
135+
136+
LIB_DIR="extensions"
137+
PREFIX="bitorch_engine"
138+
LIB_SO_RPATH='$ORIGIN/../../torch/lib:$ORIGIN'
139+
FORCE_RPATH="--force-rpath"
140+
141+
#######################################################################
142+
# do not remove (license notice):
143+
# code below was copied and modified from:
144+
# https://github.com/pytorch/builder/blob/main/manywheel/build_common.sh
145+
# it was released under BSD-2-Clause License
146+
#######################################################################
147+
# ADD DEPENDENCIES INTO THE WHEEL
148+
#
149+
# auditwheel repair doesn't work correctly and is buggy
150+
# so manually do the work of copying dependency libs and patchelfing
151+
# and fixing RECORDS entries correctly
152+
######################################################################
153+
154+
fname_with_sha256() {
155+
HASH=$(sha256sum $1 | cut -c1-8)
156+
DIRNAME=$(dirname $1)
157+
BASENAME=$(basename $1)
158+
# Do not rename nvrtc-builtins.so as they are dynamically loaded
159+
# by libnvrtc.so
160+
# Similarly don't mangle libcudnn and libcublas library names
161+
if [[ $BASENAME == "libnvrtc-builtins.s"* || $BASENAME == "libcudnn"* || $BASENAME == "libcublas"* ]]; then
162+
echo $1
163+
else
164+
INITNAME=$(echo $BASENAME | cut -f1 -d".")
165+
ENDNAME=$(echo $BASENAME | cut -f 2- -d".")
166+
echo "$DIRNAME/$INITNAME-$HASH.$ENDNAME"
167+
fi
168+
}
169+
170+
fname_without_so_number() {
171+
LINKNAME=$(echo $1 | sed -e 's/\.so.*/.so/g')
172+
echo "$LINKNAME"
173+
}
174+
175+
make_wheel_record() {
176+
FPATH=$1
177+
if echo $FPATH | grep RECORD >/dev/null 2>&1; then
178+
# if the RECORD file, then
179+
echo "$FPATH,,"
180+
else
181+
HASH=$(openssl dgst -sha256 -binary $FPATH | openssl base64 | sed -e 's/+/-/g' | sed -e 's/\//_/g' | sed -e 's/=//g')
182+
FSIZE=$(ls -nl $FPATH | awk '{print $5}')
183+
echo "$FPATH,sha256=$HASH,$FSIZE"
184+
fi
185+
}
186+
187+
replace_needed_sofiles() {
188+
find $1 -name '*.so*' | while read sofile; do
189+
origname=$2
190+
patchedname=$3
191+
if [[ "$origname" != "$patchedname" ]] || [[ "$DESIRED_CUDA" == *"rocm"* ]]; then
192+
set +e
193+
origname=$($PATCHELF_BIN --print-needed $sofile | grep "$origname.*")
194+
ERRCODE=$?
195+
set -e
196+
if [ "$ERRCODE" -eq "0" ]; then
197+
echo "patching $sofile entry $origname to $patchedname"
198+
$PATCHELF_BIN --replace-needed $origname $patchedname $sofile
199+
fi
200+
fi
201+
done
202+
}
203+
204+
echo 'Built this wheel:'
205+
ls /bitorch-engine/dist
206+
207+
mkdir /tmp_dir
208+
pushd /tmp_dir
209+
210+
for pkg in /bitorch-engine/dist/bitorch_engine*linux*.whl; do
211+
212+
# if the glob didn't match anything
213+
if [[ ! -e $pkg ]]; then
214+
continue
215+
fi
216+
217+
rm -rf tmp
218+
mkdir -p tmp
219+
cd tmp
220+
cp $pkg .
221+
222+
unzip -q $(basename $pkg)
223+
rm -f $(basename $pkg)
224+
225+
# set RPATH of $LIB_DIR/ files to $ORIGIN
226+
find $PREFIX/$LIB_DIR -maxdepth 1 -type f -name "*.so*" | while read sofile; do
227+
echo "Setting rpath of $sofile to ${LIB_SO_RPATH:-'$ORIGIN'}"
228+
$PATCHELF_BIN --set-rpath ${LIB_SO_RPATH:-'$ORIGIN'} ${FORCE_RPATH:-} $sofile
229+
$PATCHELF_BIN --print-rpath $sofile
230+
done
231+
232+
# regenerate the RECORD file with new hashes
233+
record_file=$(echo $(basename $pkg) | sed -e 's/-cp.*$/.dist-info\/RECORD/g')
234+
if [[ -e $record_file ]]; then
235+
echo "Generating new record file $record_file"
236+
: > "$record_file"
237+
# generate records for folders in wheel
238+
find * -type f | while read fname; do
239+
make_wheel_record "$fname" >>"$record_file"
240+
done
241+
fi
242+
243+
# zip up the wheel back
244+
# todo: determine if typo should be fixed or not
245+
zip -rq $(basename $pkg) $PREIX*
246+
247+
# replace original wheel
248+
rm -f $pkg
249+
mv $(basename $pkg) $pkg
250+
chown "${USER_ID}:${GROUP_ID}" $pkg
251+
cd ..
252+
rm -rf tmp
253+
done
254+
########################################################################
255+
# do not remove (license notice):
256+
# code above was copied and modified from https://github.com/pytorch/builder/blob/main/manywheel/build_common.sh
257+
# released under BSD-2-Clause License
258+
#######################################################################
259+
123260
echo "To publish to real PyPI use:"
124261
echo " python3 -m twine dist-${PUBLISH_BIE_VERSION}/*"
125262
echo "To publish to test PyPI use:"

.dev-scripts/publish-with-docker.sh

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function usage() {
77
echo "builds a package and publishes it to (test-)pypi"
88
echo
99
echo "BIE_VERSION must be a version string like 'v1.2.3'."
10-
echo "optional: CUDA_VERSION can be either '11.8' (default) or '12.1'."
10+
echo "optional: CUDA_VERSION can be either '11.8' (not yet supported) or '12.1'. (default)"
1111
}
1212

1313
trap exit INT
@@ -18,7 +18,7 @@ if ! ((1 <= $# && $# <= 2)) || [ "${1}" = "-h" ]; then
1818
fi
1919

2020
export PUBLISH_BIE_VERSION="${1}"
21-
CUDA_VERSION="${2:-11.8}"
21+
CUDA_VERSION="${2:-12.1}"
2222

2323
if ! [[ "${PUBLISH_BIE_VERSION}" =~ ^v[0-9].[0-9].[0-9]$ ]]; then
2424
echo "Invalid BIE_VERSION '${PUBLISH_BIE_VERSION}' given."
@@ -28,18 +28,21 @@ if ! [[ "${PUBLISH_BIE_VERSION}" =~ ^v[0-9].[0-9].[0-9]$ ]]; then
2828
fi
2929

3030
cuda_known="false"
31-
add_build_arg=""
31+
build_args=""
3232
cuda_abbrev="unknown"
33+
# TODO: check support for 11.8:
3334
if [ "${CUDA_VERSION}" = "11.8" ]; then
3435
cuda_known="true"
3536
cuda_abbrev="cu118"
36-
torch_requirement="torch==2.2.2"
37+
torch_requirement="torch==2.3.0"
38+
build_args="${build_args} --build-arg FROM_IMAGE=pytorch/manylinux-builder:cuda11.8-2.3"
39+
build_args="${build_args} --build-arg CUSTOM_TORCH_URL=https://packages.greenbit.ai/whl/cu118/torch/torch-2.3.0-cp310-cp310-linux_x86_64.whl"
40+
build_args="${build_args} --build-arg TORCHVISION_INDEX_URL=https://download.pytorch.org/whl/cu118"
3741
fi
3842
if [ "${CUDA_VERSION}" = "12.1" ]; then
3943
cuda_known="true"
4044
cuda_abbrev="cu121"
41-
add_build_arg="--build-arg FROM_IMAGE=pytorch/pytorch:2.2.0-cuda12.1-cudnn8-devel"
42-
torch_requirement="torch==2.2.2"
45+
torch_requirement="torch==2.3.0"
4346
fi
4447
if [ "${cuda_known}" = "false" ]; then
4548
echo "Unknown CUDA_VERSION '${CUDA_VERSION}' given."
@@ -57,9 +60,11 @@ output_folder="./dist/${cuda_abbrev}"
5760

5861
# build/tag docker image
5962
pushd docker
60-
docker build --target no-examples ${add_build_arg} --build-arg GIT_BRANCH="${PUBLISH_BIE_VERSION}" -t "${bie_image_tag}" .
63+
docker build --target no-examples ${build_args} --build-arg GIT_BRANCH="${PUBLISH_BIE_VERSION}" -t "${bie_image_tag}" .
6164
popd
6265

66+
mkdir -p "${output_folder}"
67+
6368
docker container create -it \
6469
--rm \
6570
-it \
@@ -68,6 +73,8 @@ docker container create -it \
6873
-e PUBLISH_BIE_VERSION \
6974
-e BIE_FORCE_CUDA="true" \
7075
-e BIE_SKIP_BUILD="true" \
76+
-e USER_ID="$(id -u)" \
77+
-e GROUP_ID="$(id -g)" \
7178
-e BIE_TORCH_REQUIREMENT="${torch_requirement}" \
7279
-e BIE_WHEEL_PLATFORM="linux_x86_64" \
7380
-w /bitorch-engine \

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

77

8+
## [0.2.6] - 2024/06/14
9+
10+
### Added
11+
12+
- Installation instructions for binary releases
13+
- Warning if non-customized PyTorch version is detected which can not calculate gradients for non-complex tensor types
14+
15+
### Changed
16+
17+
- Updated development scripts for binary releases
18+
- Adjusting rpaths in .so files (based on PyTorch's implemented solution)
19+
- Docker base image changed to manywheel builder image
20+
821
## [0.2.5] - 2024/05/24
922

1023
### Added

0 commit comments

Comments
 (0)