test.sh 13.6 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
    cffi \
134
135
136
137
138
    cloudpickle \
    joblib \
    matplotlib \
    numpy \
    psutil \
139
    pyarrow \
140
    pytest \
141
    ${CONDA_PYTHON_REQUIREMENT} \
142
    python-graphviz \
143
144
    scikit-learn \
    scipy || exit -1
145

146
147
148
149
source activate $CONDA_ENV

cd $BUILD_DIRECTORY

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

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

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

285
make _lightgbm -j4 || exit -1
Guolin Ke's avatar
Guolin Ke committed
286

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

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

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