test.sh 13.5 KB
Newer Older
Guolin Ke's avatar
Guolin Ke committed
1
2
#!/bin/bash

3
if [[ $OS_NAME == "macos" ]] && [[ $COMPILER == "gcc" ]]; then
4
5
    export CXX=g++-11
    export CC=gcc-11
6
elif [[ $OS_NAME == "linux" ]] && [[ $COMPILER == "clang" ]]; then
7
8
    export CXX=clang++
    export CC=clang
Guolin Ke's avatar
Guolin Ke committed
9
10
fi

11
12
13
14
15
if [[ $IN_UBUNTU_BASE_CONTAINER == "true" ]]; then
    export LANG="en_US.UTF-8"
    export LC_ALL="en_US.UTF-8"
fi

16
if [[ "${TASK}" == "r-package" ]] || [[ "${TASK}" == "r-rchk" ]]; then
17
18
19
20
    bash ${BUILD_DIRECTORY}/.ci/test_r_package.sh || exit -1
    exit 0
fi

21
22
if [[ "$TASK" == "cpp-tests" ]]; then
    mkdir $BUILD_DIRECTORY/build && cd $BUILD_DIRECTORY/build
23
24
25
26
27
28
29
30
31
    if [[ $METHOD == "with-sanitizers" ]]; then
        extra_cmake_opts="-DUSE_SANITIZER=ON"
        if [[ -n $SANITIZERS ]]; then
            extra_cmake_opts="$extra_cmake_opts -DENABLED_SANITIZERS=$SANITIZERS"
        fi
    else
        extra_cmake_opts=""
    fi
    cmake -DBUILD_CPP_TEST=ON -DUSE_OPENMP=OFF -DUSE_DEBUG=ON $extra_cmake_opts ..
32
33
34
35
36
    make testlightgbm -j4 || exit -1
    ./../testlightgbm || exit -1
    exit 0
fi

37
38
39
CONDA_PYTHON_REQUIREMENT="python=$PYTHON_VERSION[build=*cpython]"

if [[ $TASK == "if-else" ]]; then
40
    mamba create -q -y -n $CONDA_ENV ${CONDA_PYTHON_REQUIREMENT} numpy
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
    source activate $CONDA_ENV
    mkdir $BUILD_DIRECTORY/build && cd $BUILD_DIRECTORY/build && cmake .. && make lightgbm -j4 || exit -1
    cd $BUILD_DIRECTORY/tests/cpp_tests && ../../lightgbm config=train.conf convert_model_language=cpp convert_model=../../src/boosting/gbdt_prediction.cpp && ../../lightgbm config=predict.conf output_result=origin.pred || exit -1
    cd $BUILD_DIRECTORY/build && make lightgbm -j4 || exit -1
    cd $BUILD_DIRECTORY/tests/cpp_tests && ../../lightgbm config=predict.conf output_result=ifelse.pred && python test.py || exit -1
    exit 0
fi

if [[ $TASK == "swig" ]]; then
    mkdir $BUILD_DIRECTORY/build && cd $BUILD_DIRECTORY/build
    if [[ $OS_NAME == "macos" ]]; then
        cmake -DUSE_SWIG=ON -DAPPLE_OUTPUT_DYLIB=ON ..
    else
        cmake -DUSE_SWIG=ON ..
    fi
    make -j4 || exit -1
    if [[ $OS_NAME == "linux" ]] && [[ $COMPILER == "gcc" ]]; then
        objdump -T $BUILD_DIRECTORY/lib_lightgbm.so > $BUILD_DIRECTORY/objdump.log || exit -1
        objdump -T $BUILD_DIRECTORY/lib_lightgbm_swig.so >> $BUILD_DIRECTORY/objdump.log || exit -1
        python $BUILD_DIRECTORY/helpers/check_dynamic_dependencies.py $BUILD_DIRECTORY/objdump.log || exit -1
    fi
    if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
        cp $BUILD_DIRECTORY/build/lightgbmlib.jar $BUILD_ARTIFACTSTAGINGDIRECTORY/lightgbmlib_$OS_NAME.jar
    fi
    exit 0
fi

if [[ $TASK == "lint" ]]; then
69
    cd ${BUILD_DIRECTORY}
70
    mamba create -q -y -n $CONDA_ENV \
71
72
73
74
75
        ${CONDA_PYTHON_REQUIREMENT} \
        cmakelint \
        cpplint \
        isort \
        mypy \
76
        'r-lintr>=3.1' \
77
        ruff
78
79
    source activate $CONDA_ENV
    echo "Linting Python code"
80
    sh ${BUILD_DIRECTORY}/.ci/lint-python.sh || exit -1
81
82
83
    echo "Linting R code"
    Rscript ${BUILD_DIRECTORY}/.ci/lint_r_code.R ${BUILD_DIRECTORY} || exit -1
    echo "Linting C++ code"
84
    sh ${BUILD_DIRECTORY}/.ci/lint-cpp.sh || exit -1
85
86
87
    exit 0
fi

88
if [[ $TASK == "check-docs" ]] || [[ $TASK == "check-links" ]]; then
89
    cd $BUILD_DIRECTORY/docs
90
    mamba env create \
91
92
        -n $CONDA_ENV \
        --file ./env.yml || exit -1
93
    mamba install \
94
95
96
97
        -q \
        -y \
        -n $CONDA_ENV \
            doxygen \
98
            'rstcheck>=6.0.0' || exit -1
99
    source activate $CONDA_ENV
100
101
    # check reStructuredText formatting
    cd $BUILD_DIRECTORY/python-package
102
    rstcheck --report-level warning $(find . -type f -name "*.rst") || exit -1
103
    cd $BUILD_DIRECTORY/docs
104
    rstcheck --report-level warning --ignore-directives=autoclass,autofunction,autosummary,doxygenfile $(find . -type f -name "*.rst") || exit -1
105
    # build docs
106
    make html || exit -1
107
108
    if [[ $TASK == "check-links" ]]; then
        # check docs for broken links
109
        pip install --user linkchecker
110
111
112
        linkchecker --config=.linkcheckerrc ./_build/html/*.html || exit -1
        exit 0
    fi
113
114
115
    # check the consistency of parameters' descriptions and other stuff
    cp $BUILD_DIRECTORY/docs/Parameters.rst $BUILD_DIRECTORY/docs/Parameters-backup.rst
    cp $BUILD_DIRECTORY/src/io/config_auto.cpp $BUILD_DIRECTORY/src/io/config_auto-backup.cpp
116
    python $BUILD_DIRECTORY/helpers/parameter_generator.py || exit -1
117
118
119
120
    diff $BUILD_DIRECTORY/docs/Parameters-backup.rst $BUILD_DIRECTORY/docs/Parameters.rst || exit -1
    diff $BUILD_DIRECTORY/src/io/config_auto-backup.cpp $BUILD_DIRECTORY/src/io/config_auto.cpp || exit -1
    exit 0
fi
121

122
123
124
125
126
# older versions of Dask are incompatible with pandas>=2.0, but not all conda packages' metadata accurately reflects that
#
# ref: https://github.com/microsoft/LightGBM/issues/6030
CONSTRAINED_DEPENDENCIES="'dask-core>=2023.5.0' 'distributed>=2023.5.0' 'pandas>=2.0'"
if [[ $PYTHON_VERSION == "3.7" ]]; then
127
    CONSTRAINED_DEPENDENCIES="'dask-core' 'distributed' 'pandas<2.0'"
128
129
fi

130
# including python=version[build=*cpython] to ensure that conda doesn't fall back to pypy
131
mamba create -q -y -n $CONDA_ENV \
132
    ${CONSTRAINED_DEPENDENCIES} \
133
134
135
136
137
138
    cloudpickle \
    joblib \
    matplotlib \
    numpy \
    psutil \
    pytest \
139
    ${CONDA_PYTHON_REQUIREMENT} \
140
    python-graphviz \
141
142
    scikit-learn \
    scipy || exit -1
143

144
145
146
147
source activate $CONDA_ENV

cd $BUILD_DIRECTORY

148
if [[ $OS_NAME == "macos" ]] && [[ $COMPILER == "clang" ]]; then
149
150
    # fix "OMP: Error #15: Initializing libiomp5.dylib, but found libomp.dylib already initialized." (OpenMP library conflict due to conda's MKL)
    for LIBOMP_ALIAS in libgomp.dylib libiomp5.dylib libomp.dylib; do sudo ln -sf "$(brew --cellar libomp)"/*/lib/libomp.dylib $CONDA_PREFIX/lib/$LIBOMP_ALIAS || exit -1; done
151
152
fi

Guolin Ke's avatar
Guolin Ke committed
153
if [[ $TASK == "sdist" ]]; then
154
155
156
    cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
    sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
    pip install --user $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz -v || exit -1
157
    if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
158
        cp $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
159
160
    fi
    pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
Guolin Ke's avatar
Guolin Ke committed
161
162
    exit 0
elif [[ $TASK == "bdist" ]]; then
163
    if [[ $OS_NAME == "macos" ]]; then
164
165
166
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
        mv \
167
            ./dist/*.whl \
168
169
170
            ./dist/tmp.whl || exit -1
        mv \
            ./dist/tmp.whl \
171
            dist/lightgbm-$LGB_VER-py3-none-macosx_10_15_x86_64.macosx_11_6_x86_64.macosx_12_5_x86_64.whl || exit -1
172
        if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
173
            cp dist/lightgbm-$LGB_VER-py3-none-macosx*.whl $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
174
        fi
Guolin Ke's avatar
Guolin Ke committed
175
    else
176
177
        ARCH=$(uname -m)
        if [[ $ARCH == "x86_64" ]]; then
178
            PLATFORM="manylinux_2_28_x86_64"
179
180
181
        else
            PLATFORM="manylinux2014_$ARCH"
        fi
182
183
184
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel --integrated-opencl || exit -1
        mv \
            ./dist/*.whl \
185
186
187
            ./dist/tmp.whl || exit -1
        mv \
            ./dist/tmp.whl \
188
            ./dist/lightgbm-$LGB_VER-py3-none-$PLATFORM.whl || exit -1
189
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
190
        if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
191
            cp dist/lightgbm-$LGB_VER-py3-none-$PLATFORM.whl $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
192
        fi
193
194
        # Make sure we can do both CPU and GPU; see tests/python_package_test/test_dual.py
        export LIGHTGBM_TEST_DUAL_CPU_GPU=1
Guolin Ke's avatar
Guolin Ke committed
195
    fi
196
    pip install --user $BUILD_DIRECTORY/dist/*.whl || exit -1
197
    pytest $BUILD_DIRECTORY/tests || exit -1
Guolin Ke's avatar
Guolin Ke committed
198
199
200
201
    exit 0
fi

if [[ $TASK == "gpu" ]]; then
202
203
    sed -i'.bak' 's/std::string device_type = "cpu";/std::string device_type = "gpu";/' $BUILD_DIRECTORY/include/LightGBM/config.h
    grep -q 'std::string device_type = "gpu"' $BUILD_DIRECTORY/include/LightGBM/config.h || exit -1  # make sure that changes were really done
Guolin Ke's avatar
Guolin Ke committed
204
    if [[ $METHOD == "pip" ]]; then
205
206
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
207
208
209
        pip install \
            --user \
            -v \
210
            --config-settings=cmake.define.USE_GPU=ON \
211
212
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
213
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
Guolin Ke's avatar
Guolin Ke committed
214
        exit 0
215
    elif [[ $METHOD == "wheel" ]]; then
216
217
218
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel --gpu || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
        pip install --user $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER*.whl -v || exit -1
219
220
221
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
222
223
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
224
        cmake -DUSE_GPU=ON ..
Guolin Ke's avatar
Guolin Ke committed
225
    fi
226
227
228
229
230
231
elif [[ $TASK == "cuda" ]]; then
    sed -i'.bak' 's/std::string device_type = "cpu";/std::string device_type = "cuda";/' $BUILD_DIRECTORY/include/LightGBM/config.h
    grep -q 'std::string device_type = "cuda"' $BUILD_DIRECTORY/include/LightGBM/config.h || exit -1  # make sure that changes were really done
    # by default ``gpu_use_dp=false`` for efficiency. change to ``true`` here for exact results in ci tests
    sed -i'.bak' 's/gpu_use_dp = false;/gpu_use_dp = true;/' $BUILD_DIRECTORY/include/LightGBM/config.h
    grep -q 'gpu_use_dp = true' $BUILD_DIRECTORY/include/LightGBM/config.h || exit -1  # make sure that changes were really done
232
    if [[ $METHOD == "pip" ]]; then
233
234
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
235
236
237
        pip install \
            --user \
            -v \
238
            --config-settings=cmake.define.USE_CUDA=ON \
239
240
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
241
242
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
        exit 0
243
    elif [[ $METHOD == "wheel" ]]; then
244
245
246
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel --cuda || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
        pip install --user $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER*.whl -v || exit -1
247
248
249
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
250
251
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
252
        cmake -DUSE_CUDA=ON ..
253
    fi
254
elif [[ $TASK == "mpi" ]]; then
255
    if [[ $METHOD == "pip" ]]; then
256
257
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
258
259
260
        pip install \
            --user \
            -v \
261
            --config-settings=cmake.define.USE_MPI=ON \
262
263
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
264
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
265
        exit 0
266
    elif [[ $METHOD == "wheel" ]]; then
267
268
269
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel --mpi || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
        pip install --user $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER*.whl -v || exit -1
270
271
272
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
273
274
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
275
        cmake -DUSE_MPI=ON -DUSE_DEBUG=ON ..
276
    fi
Guolin Ke's avatar
Guolin Ke committed
277
else
278
279
    mkdir $BUILD_DIRECTORY/build
    cd $BUILD_DIRECTORY/build
280
    cmake ..
Guolin Ke's avatar
Guolin Ke committed
281
282
fi

283
make _lightgbm -j4 || exit -1
Guolin Ke's avatar
Guolin Ke committed
284

285
cd $BUILD_DIRECTORY && sh ./build-python.sh install --precompile --user || exit -1
286
pytest $BUILD_DIRECTORY/tests || exit -1
Guolin Ke's avatar
Guolin Ke committed
287
288

if [[ $TASK == "regular" ]]; then
289
    if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
290
291
292
        if [[ $OS_NAME == "macos" ]]; then
            cp $BUILD_DIRECTORY/lib_lightgbm.so $BUILD_ARTIFACTSTAGINGDIRECTORY/lib_lightgbm.dylib
        else
293
294
295
296
            if [[ $COMPILER == "gcc" ]]; then
                objdump -T $BUILD_DIRECTORY/lib_lightgbm.so > $BUILD_DIRECTORY/objdump.log || exit -1
                python $BUILD_DIRECTORY/helpers/check_dynamic_dependencies.py $BUILD_DIRECTORY/objdump.log || exit -1
            fi
297
298
            cp $BUILD_DIRECTORY/lib_lightgbm.so $BUILD_ARTIFACTSTAGINGDIRECTORY/lib_lightgbm.so
        fi
Guolin Ke's avatar
Guolin Ke committed
299
    fi
300
    cd $BUILD_DIRECTORY/examples/python-guide
Guolin Ke's avatar
Guolin Ke committed
301
302
303
304
    sed -i'.bak' '/import lightgbm as lgb/a\
import matplotlib\
matplotlib.use\(\"Agg\"\)\
' plot_example.py  # prevent interactive window mode
305
    sed -i'.bak' 's/graph.render(view=True)/graph.render(view=False)/' plot_example.py
306
    # requirements for examples
307
    mamba install -q -y -n $CONDA_ENV \
308
309
310
        h5py \
        ipywidgets \
        notebook
311
    for f in *.py **/*.py; do python $f || exit -1; done  # run all examples
312
    cd $BUILD_DIRECTORY/examples/python-guide/notebooks
313
    sed -i'.bak' 's/INTERACTIVE = False/assert False, \\"Interactive mode disabled\\"/' interactive_plot_example.ipynb
314
    jupyter nbconvert --ExecutePreprocessor.timeout=180 --to notebook --execute --inplace *.ipynb || exit -1  # run all notebooks
315
316
317
318
319
320
321
322
323
324
325

    # importing the library should succeed even if all optional dependencies are not present
    conda uninstall --force --yes \
        dask \
        distributed \
        joblib \
        matplotlib \
        psutil \
        python-graphviz \
        scikit-learn || exit -1
    python -c "import lightgbm" || exit -1
Guolin Ke's avatar
Guolin Ke committed
326
fi