diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml index 052a82a304..39bbf2e26a 100644 --- a/.github/workflows/generate-docs.yml +++ b/.github/workflows/generate-docs.yml @@ -55,31 +55,28 @@ jobs: with: fetch-depth: 0 persist-credentials: false - - name: Build dpctl - if: ${{ !github.event.pull_request || github.event.action != 'closed' }} - shell: bash -l {0} - run: | - source /opt/intel/oneapi/setvars.sh - python setup.py develop -- -DCMAKE_C_COMPILER:PATH=icx -DCMAKE_CXX_COMPILER:PATH=icpx -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON -DDPCTL_DPCPP_HOME_DIR=${BUILD_PREFIX} - python -c "import dpctl; print(dpctl.__version__)" || exit 1 - - name: Build docs + - name: Build dpctl+docs if: ${{ !github.event.pull_request || github.event.action != 'closed' }} shell: bash -l {0} run: | # Ensure that SYCL libraries are on LD_LIBRARY_PATH source /opt/intel/oneapi/setvars.sh - cd docs - mkdir -p build && cd build && rm -rf * wget https://github.com/vovkos/doxyrest/releases/download/doxyrest-2.1.2/doxyrest-2.1.2-linux-amd64.tar.xz tar xf doxyrest-2.1.2-linux-amd64.tar.xz - cmake .. -DDPCTL_USE_MULTIVERSION_TEMPLATE=ON \ - -DDPCTL_ENABLE_DOXYREST=ON \ - -DDoxyrest_DIR=`pwd`/doxyrest-2.1.2-linux-amd64 - make Sphinx || exit 1 - cd .. - mv generated_docs/docs ~/docs + python setup.py develop -- \ + -G "Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_C_COMPILER:PATH=icx \ + -DCMAKE_CXX_COMPILER:PATH=icpx \ + -DDPCTL_ENABLE_LO_PROGRAM_CREATION=ON \ + -DDPCTL_GENERATE_DOCS=ON \ + -DDPCTL_ENABLE_DOXYREST=ON \ + -DDoxyrest_DIR=`pwd`/doxyrest-2.1.2-linux-amd64 + python -c "import dpctl; print(dpctl.__version__)" || exit 1 + cd "$(find _skbuild -name cmake-build)" || exit 1 + cmake --build . --target Sphinx || exit 1 + mv ../cmake-install/docs/docs ~/docs git clean -dfx - cd .. - name: Publish docs if: ${{ github.ref == 'refs/heads/master' }} shell: bash -l {0} diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 82e8e1a0e1..ff3fbcb7cd 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,6 +1,3 @@ -cmake_minimum_required(VERSION 3.18 FATAL_ERROR) -project("Data-parallel Control (dpctl)") - # Option to generate rst for C API and add to Sphinx documentation option(DPCTL_ENABLE_DOXYREST "Enable generation of rst files for C API" @@ -55,7 +52,6 @@ function(_setup_doxygen) # Target to generate only Doxygen documentation add_custom_target( Doxygen - ALL DEPENDS ${DOXYGEN_INDEX_FILE} ) endfunction() @@ -95,7 +91,6 @@ function(_setup_doxyrest) # Target to generate rst from Doxygen XML using Doxyrest add_custom_target( Doxyrest - ALL DEPENDS Doxygen ${DOXYREST_OUTPUT} ) endfunction() @@ -147,7 +142,6 @@ function(_setup_sphinx) # important, we want the rst files to generate prior to sphinx build. add_custom_target( Sphinx - ALL DEPENDS ${DEPEND_ON_DOXYREST} ${DPCTL_PYAPI_RST_FILE} @@ -196,12 +190,7 @@ if (DPCTL_ENABLE_DOXYREST) endif() # Set the location where the generated docs are saved -if(DPCTL_DOCGEN_PREFIX) - message(STATUS "Generating dpctl documents in " ${DPCTL_DOCGEN_PREFIX}) - set(DOC_OUTPUT_DIR ${DPCTL_DOCGEN_PREFIX}) -else() - set(DOC_OUTPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/generated_docs) -endif() +set(DOC_OUTPUT_DIR ${CMAKE_INSTALL_PREFIX}/docs) set(INDEX_NO_DOXYREST_IN ${CMAKE_CURRENT_SOURCE_DIR}/index_no_doxyrest.rst.in) set(INDEX_DOXYREST_IN ${CMAKE_CURRENT_SOURCE_DIR}/index_doxyrest.rst.in) diff --git a/docs/README.md b/docs/README.md index 20e696f1a2..075889c9af 100644 --- a/docs/README.md +++ b/docs/README.md @@ -32,58 +32,13 @@ sudo apt-get install liblua5.2-dev Generating the docs =================== -The documentation should be generated using the provided `Cmake` build script. -There are a few configurable options that can be used to select the type of -documentation to generate. +The helper script ``scripts/gen_docs.py`` is the preferred way to generate the +documentation. The generated documentation html pages will be installed to the +``CMAKE_INSTALL_PREFIX/docs`` directory. -Build only Doxygen for C API ---------------------------- ```bash -cd dpctl/docs -mkdir -p build -cd build -cmake .. -make Doxygen +python scripts/gen_docs.py --doxyrest-root= ``` -The above steps will generate the `Doxygen` files at -`dpctl/docs/generated_docs/doxygen/html`. The documentation can also be -generated at a custom location by providing the optional flag - -```bash -cd dpctl/docs -mkdir -p build -cd build -cmake .. -DDPCTL_DOCGEN_PREFIX= -make Doxygen -``` - -Build only Sphinx for Python API --------------------------------- -```bash -cd dpctl/docs -mkdir -p build -cd build -cmake .. -DDPCTL_DOCGEN_PREFIX= -make Sphinx -``` - -The `make Sphinx` command will generate only the Python API docs for dpctl. - -Build consolidated docs ------------------------ -It is possible to generate a single site with both Python and C API docs. As -mentioned before, `Doxyrest` and `Lua` are required to generate the consolidated -site. - -```bash -cd dpctl/docs -mkdir -p build -cd build -cmake .. \ - -DDPCTL_ENABLE_DOXYREST=ON \ - -DDoxyrest_DIR= \ - -DDPCTL_DOCGEN_PREFIX= -make Sphinx -``` -The `Doxyrest_DIR` flag is optional, but is needed when Doxyrest is installed in -a non-system location. +To skip generating the documentation for ``libsyclinterface``, the +``--doxyrest-root`` option should be omitted. diff --git a/scripts/build_locally.py b/scripts/build_locally.py index d6c258d823..19b811f376 100644 --- a/scripts/build_locally.py +++ b/scripts/build_locally.py @@ -1,3 +1,19 @@ +# Data Parallel Control (dpctl) +# +# Copyright 2020-2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import subprocess import sys diff --git a/scripts/gen_coverage.py b/scripts/gen_coverage.py index 68ad75ea52..43cffd1cd9 100644 --- a/scripts/gen_coverage.py +++ b/scripts/gen_coverage.py @@ -1,3 +1,19 @@ +# Data Parallel Control (dpctl) +# +# Copyright 2020-2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import os import subprocess import sys diff --git a/scripts/gen_docs.py b/scripts/gen_docs.py new file mode 100644 index 0000000000..9b5435c475 --- /dev/null +++ b/scripts/gen_docs.py @@ -0,0 +1,171 @@ +# Data Parallel Control (dpctl) +# +# Copyright 2020-2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import subprocess +import sys + + +def run( + use_oneapi=True, + c_compiler=None, + cxx_compiler=None, + level_zero=True, + compiler_root=None, + bin_llvm=None, + doxyrest_dir=None, +): + IS_LIN = False + + if "linux" in sys.platform: + IS_LIN = True + elif sys.platform in ["win32", "cygwin"]: + pass + else: + assert False, sys.platform + " not supported" + + if not IS_LIN: + raise RuntimeError( + "This scripts only supports coverage collection on Linux" + ) + setup_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + cmake_args = [ + sys.executable, + "setup.py", + "develop", + "--", + "-G", + "Unix Makefiles", + "-DCMAKE_BUILD_TYPE=Debug", + "-DCMAKE_C_COMPILER:PATH=" + c_compiler, + "-DCMAKE_CXX_COMPILER:PATH=" + cxx_compiler, + "-DDPCTL_ENABLE_LO_PROGRAM_CREATION=" + ("ON" if level_zero else "OFF"), + "-DDPCTL_DPCPP_FROM_ONEAPI:BOOL=" + ("ON" if use_oneapi else "OFF"), + "-DDPCTL_GENERATE_DOCS=ON", + ] + + if doxyrest_dir: + cmake_args.append("-DDPCTL_ENABLE_DOXYREST=ON") + cmake_args.append("-DDoxyrest_DIR=" + doxyrest_dir) + + if compiler_root: + cmake_args += [ + "-DDPCTL_DPCPP_HOME_DIR:PATH=" + compiler_root, + ] + env = None + if bin_llvm: + env = { + "PATH": ":".join((os.environ.get("PATH", ""), bin_llvm)), + } + env.update({k: v for k, v in os.environ.items() if k != "PATH"}) + # Install dpctl package + subprocess.check_call(cmake_args, shell=False, cwd=setup_dir, env=env) + # Get the path for the build directory + build_dir = ( + subprocess.check_output( + ["find", "_skbuild", "-name", "cmake-build"], + cwd=setup_dir, + ) + .decode("utf-8") + .strip("\n") + ) + # Generate docs + subprocess.check_call( + ["cmake", "--build", ".", "--target", "Sphinx"], cwd=build_dir + ) + generated_doc_dir = ( + subprocess.check_output( + ["find", "_skbuild", "-name", "index.html"], cwd=setup_dir + ) + .decode("utf-8") + .strip("\n") + ) + print("Generated documentation placed under ", generated_doc_dir) + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser( + description="Driver to build dpctl and generate coverage" + ) + driver = parser.add_argument_group(title="Coverage driver arguments") + driver.add_argument("--c-compiler", help="Name of C compiler", default=None) + driver.add_argument( + "--cxx-compiler", help="Name of C++ compiler", default=None + ) + driver.add_argument( + "--not-oneapi", + help="Is one-API installation", + dest="oneapi", + action="store_false", + ) + driver.add_argument( + "--compiler-root", type=str, help="Path to compiler home directory" + ) + driver.add_argument( + "--no-level-zero", + help="Enable Level Zero support", + dest="level_zero", + action="store_false", + ) + driver.add_argument( + "--bin-llvm", help="Path to folder where llvm-cov can be found" + ) + driver.add_argument( + "--doxyrest-root", + help=( + "Path to Doxyrest installation to use to generate Sphinx docs" + + "for libsyclinterface" + ), + ) + + args = parser.parse_args() + + if args.oneapi: + args.c_compiler = "icx" + args.cxx_compiler = "icpx" + args.compiler_root = None + icx_path = subprocess.check_output(["which", "icx"]) + bin_dir = os.path.dirname(os.path.dirname(icx_path)) + args.bin_llvm = os.path.join(bin_dir.decode("utf-8"), "bin-llvm") + else: + args_to_validate = [ + "c_compiler", + "cxx_compiler", + "compiler_root", + "bin_llvm", + ] + for p in args_to_validate: + arg = getattr(args, p, None) + if not isinstance(arg, str): + opt_name = p.replace("_", "-") + raise RuntimeError( + f"Option {opt_name} must be provided is " + "using non-default DPC++ layout" + ) + if not os.path.exists(arg): + raise RuntimeError(f"Path {arg} must exist") + + run( + use_oneapi=args.oneapi, + c_compiler=args.c_compiler, + cxx_compiler=args.cxx_compiler, + level_zero=args.level_zero, + compiler_root=args.compiler_root, + bin_llvm=args.bin_llvm, + doxyrest_dir=args.doxyrest_root, + )