test.sh 13.7 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
9
10
11
elif [[ $OS_NAME == "linux" ]] && [[ $COMPILER == "clang-17" ]]; then
    export CXX=clang++-17
    export CC=clang-17
Guolin Ke's avatar
Guolin Ke committed
12
13
fi

14
15
16
17
18
if [[ $IN_UBUNTU_BASE_CONTAINER == "true" ]]; then
    export LANG="en_US.UTF-8"
    export LC_ALL="en_US.UTF-8"
fi

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

24
25
if [[ "$TASK" == "cpp-tests" ]]; then
    mkdir $BUILD_DIRECTORY/build && cd $BUILD_DIRECTORY/build
26
27
28
29
30
31
32
33
34
    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 ..
35
36
37
38
39
    make testlightgbm -j4 || exit -1
    ./../testlightgbm || exit -1
    exit 0
fi

40
41
42
CONDA_PYTHON_REQUIREMENT="python=$PYTHON_VERSION[build=*cpython]"

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

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

125
126
127
128
129
# 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
130
    CONSTRAINED_DEPENDENCIES="'dask-core' 'distributed' 'pandas<2.0'"
131
132
fi

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

149
150
151
152
source activate $CONDA_ENV

cd $BUILD_DIRECTORY

153
if [[ $OS_NAME == "macos" ]] && [[ $COMPILER == "clang" ]]; then
154
155
    # 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
156
157
fi

Guolin Ke's avatar
Guolin Ke committed
158
if [[ $TASK == "sdist" ]]; then
159
160
161
    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
162
    if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
163
        cp $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
164
165
    fi
    pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
Guolin Ke's avatar
Guolin Ke committed
166
167
    exit 0
elif [[ $TASK == "bdist" ]]; then
168
    if [[ $OS_NAME == "macos" ]]; then
169
170
171
        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 \
172
            ./dist/*.whl \
173
174
175
            ./dist/tmp.whl || exit -1
        mv \
            ./dist/tmp.whl \
176
            dist/lightgbm-$LGB_VER-py3-none-macosx_10_15_x86_64.macosx_11_6_x86_64.macosx_12_5_x86_64.whl || exit -1
177
        if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
178
            cp dist/lightgbm-$LGB_VER-py3-none-macosx*.whl $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
179
        fi
Guolin Ke's avatar
Guolin Ke committed
180
    else
181
182
        ARCH=$(uname -m)
        if [[ $ARCH == "x86_64" ]]; then
183
            PLATFORM="manylinux_2_28_x86_64"
184
185
186
        else
            PLATFORM="manylinux2014_$ARCH"
        fi
187
188
189
        cd $BUILD_DIRECTORY && sh ./build-python.sh bdist_wheel --integrated-opencl || exit -1
        mv \
            ./dist/*.whl \
190
191
192
            ./dist/tmp.whl || exit -1
        mv \
            ./dist/tmp.whl \
193
            ./dist/lightgbm-$LGB_VER-py3-none-$PLATFORM.whl || exit -1
194
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
195
        if [[ $PRODUCES_ARTIFACTS == "true" ]]; then
196
            cp dist/lightgbm-$LGB_VER-py3-none-$PLATFORM.whl $BUILD_ARTIFACTSTAGINGDIRECTORY || exit -1
197
        fi
198
199
        # 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
200
    fi
201
    pip install --user $BUILD_DIRECTORY/dist/*.whl || exit -1
202
    pytest $BUILD_DIRECTORY/tests || exit -1
Guolin Ke's avatar
Guolin Ke committed
203
204
205
206
    exit 0
fi

if [[ $TASK == "gpu" ]]; then
207
208
    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
209
    if [[ $METHOD == "pip" ]]; then
210
211
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
212
213
214
        pip install \
            --user \
            -v \
215
            --config-settings=cmake.define.USE_GPU=ON \
216
217
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
218
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
Guolin Ke's avatar
Guolin Ke committed
219
        exit 0
220
    elif [[ $METHOD == "wheel" ]]; then
221
222
223
        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
224
225
226
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
227
228
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
229
        cmake -DUSE_GPU=ON ..
Guolin Ke's avatar
Guolin Ke committed
230
    fi
231
232
233
234
235
236
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
237
    if [[ $METHOD == "pip" ]]; then
238
239
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
240
241
242
        pip install \
            --user \
            -v \
243
            --config-settings=cmake.define.USE_CUDA=ON \
244
245
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
246
247
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
        exit 0
248
    elif [[ $METHOD == "wheel" ]]; then
249
250
251
        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
252
253
254
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
255
256
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
257
        cmake -DUSE_CUDA=ON ..
258
    fi
259
elif [[ $TASK == "mpi" ]]; then
260
    if [[ $METHOD == "pip" ]]; then
261
262
        cd $BUILD_DIRECTORY && sh ./build-python.sh sdist || exit -1
        sh $BUILD_DIRECTORY/.ci/check_python_dists.sh $BUILD_DIRECTORY/dist || exit -1
263
264
265
        pip install \
            --user \
            -v \
266
            --config-settings=cmake.define.USE_MPI=ON \
267
268
            $BUILD_DIRECTORY/dist/lightgbm-$LGB_VER.tar.gz \
        || exit -1
269
        pytest $BUILD_DIRECTORY/tests/python_package_test || exit -1
270
        exit 0
271
    elif [[ $METHOD == "wheel" ]]; then
272
273
274
        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
275
276
277
        pytest $BUILD_DIRECTORY/tests || exit -1
        exit 0
    elif [[ $METHOD == "source" ]]; then
278
279
        mkdir $BUILD_DIRECTORY/build
        cd $BUILD_DIRECTORY/build
280
        cmake -DUSE_MPI=ON -DUSE_DEBUG=ON ..
281
    fi
Guolin Ke's avatar
Guolin Ke committed
282
else
283
284
    mkdir $BUILD_DIRECTORY/build
    cd $BUILD_DIRECTORY/build
285
    cmake ..
Guolin Ke's avatar
Guolin Ke committed
286
287
fi

288
make _lightgbm -j4 || exit -1
Guolin Ke's avatar
Guolin Ke committed
289

290
cd $BUILD_DIRECTORY && sh ./build-python.sh install --precompile --user || exit -1
291
pytest $BUILD_DIRECTORY/tests || exit -1
Guolin Ke's avatar
Guolin Ke committed
292
293

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

    # importing the library should succeed even if all optional dependencies are not present
322
    conda uninstall -n $CONDA_ENV --force --yes \
323
        cffi \
324
        dask-core \
325
326
327
328
        distributed \
        joblib \
        matplotlib \
        psutil \
329
        pyarrow \
330
331
332
        python-graphviz \
        scikit-learn || exit -1
    python -c "import lightgbm" || exit -1
Guolin Ke's avatar
Guolin Ke committed
333
fi