개발

이 문서에는 개발 환경을 설정하고 다양한 플랫폼의 소스에서 tensorflow-io 패키지를 빌드하는 데 필요한 정보가 포함되어 있습니다. 설정이 완료되면 STYLE_GUIDE 에서 새 작업 추가에 대한 지침을 참조하세요.

IDE 설정

TensorFlow I/O 개발을 위해 Visual Studio Code를 구성하는 방법에 대한 지침은 이 문서를 참조하세요.

린트

TensorFlow I/O의 코드는 Bazel Buildifier, Clang Format, Black 및 Pyupgrade를 준수합니다. 소스 코드를 확인하고 Lint 문제를 식별하려면 다음 명령을 사용하십시오.

# Install Bazel version specified in .bazelversion
$ curl -OL https://github.com/bazelbuild/bazel/releases/download/$(cat .bazelversion)/bazel-$(cat .bazelversion)-installer-darwin-x86_64.sh
$ sudo bash -x -e bazel-$(cat .bazelversion)-installer-darwin-x86_64.sh
$ bazel run //tools/lint:check

Bazel Buildifier 및 Clang 형식의 경우 다음 명령은 Lint 오류를 자동으로 식별하고 수정합니다.

$ bazel run //tools/lint:lint

또는 개별 린터를 사용하여 린트 검사만 수행하려는 경우 위 명령에 black , pyupgrade , bazel 또는 clang 선택적으로 전달할 수 있습니다.

예를 들어, black 특정 린트 검사는 다음을 사용하여 수행할 수 있습니다.

$ bazel run //tools/lint:check -- black

Bazel Buildifier 및 Clang 형식을 사용한 Lint 수정은 다음을 사용하여 수행할 수 있습니다.

$ bazel run //tools/lint:lint -- bazel clang

개별 Python 파일에 대해 blackpyupgrade 사용하는 Lint 검사는 다음을 사용하여 수행할 수 있습니다.

$ bazel run //tools/lint:check -- black pyupgrade -- tensorflow_io/python/ops/version_ops.py

Lint는 다음을 사용하여 black 및 pyupgrade로 개별 Python 파일을 수정합니다.

$ bazel run //tools/lint:lint -- black pyupgrade --  tensorflow_io/python/ops/version_ops.py

파이썬

맥 OS

macOS Catalina 10.15.7에서는 Python 3.8.2가 제공되는 시스템을 사용하여 tensorflow-io를 빌드할 수 있습니다. 이를 위해서는 tensorflowbazel 모두 필요합니다.

#!/usr/bin/env bash

# Disable arm64 build by specifying only x86_64 arch.
# Only needed for macOS's system default python 3.8.2 on macOS 10.15.7
export ARCHFLAGS="-arch x86_64"

# Use following command to check if Xcode is correctly installed:
xcodebuild -version

# Show macOS's default python3
python3 --version

# Install Bazel version specified in .bazelversion
curl -OL https://github.com/bazelbuild/bazel/releases/download/$(cat .bazelversion)/bazel-$(cat .bazelversion)-installer-darwin-x86_64.sh
sudo bash -x -e bazel-$(cat .bazelversion)-installer-darwin-x86_64.sh

# Install tensorflow and configure bazel
sudo ./configure.sh

# Add any optimization on bazel command, e.g., --compilation_mode=opt,
#   --copt=-msse4.2, --remote_cache=, etc.
# export BAZEL_OPTIMIZATION=

# Build shared libraries
bazel build -s --verbose_failures $BAZEL_OPTIMIZATION //tensorflow_io/... //tensorflow_io_gcs_filesystem/...

# Once build is complete, shared libraries will be available in
# `bazel-bin/tensorflow_io/core`, `bazel-bin/tensorflow_io/python/ops` and
# it is possible to run tests with `pytest`, e.g.:
sudo python3 -m pip install pytest
TFIO_DATAPATH=bazel-bin python3 -m pytest -s -v tests/test_serialization.py
문제 해결

Xcode가 설치되었지만 $ xcodebuild -version 예상된 출력을 표시하지 않는 경우 다음 명령을 사용하여 Xcode 명령줄을 활성화해야 할 수 있습니다.

$ xcode-select -s /Applications/Xcode.app/Contents/Developer .

변경 사항을 적용하려면 터미널을 다시 시작해야 할 수도 있습니다.

샘플 출력:

$ xcodebuild -version
Xcode 12.2
Build version 12B45b

리눅스

Linux에서의 tensorflow-io 개발은 macOS와 유사합니다. 필수 패키지는 gcc, g++, git, bazel 및 python 3입니다. 그러나 기본 시스템 설치 버전이 아닌 최신 버전의 gcc 또는 python이 필요할 수 있습니다.

우분투 20.04

Ubuntu 20.04에는 gcc/g++, git 및 python 3이 필요합니다. 다음은 Ubuntu 20.04에 종속성을 설치하고 공유 라이브러리를 빌드합니다.

#!/usr/bin/env bash

# Install gcc/g++, git, unzip/curl (for bazel), and python3
sudo apt-get -y -qq update
sudo apt-get -y -qq install gcc g++ git unzip curl python3-pip

# Install Bazel version specified in .bazelversion
curl -sSOL <a href="https://github.com/bazelbuild/bazel/releases/download/">https://github.com/bazelbuild/bazel/releases/download/</a>\\((cat .bazelversion)/bazel-\\)(cat .bazelversion)-installer-linux-x86_64.sh
sudo bash -x -e bazel-$(cat .bazelversion)-installer-linux-x86_64.sh

# Upgrade pip
sudo python3 -m pip install -U pip

# Install tensorflow and configure bazel
sudo ./configure.sh

# Alias python3 to python, needed by bazel
sudo ln -s /usr/bin/python3 /usr/bin/python

# Add any optimization on bazel command, e.g., --compilation_mode=opt,
#   --copt=-msse4.2, --remote_cache=, etc.
# export BAZEL_OPTIMIZATION=

# Build shared libraries
bazel build -s --verbose_failures $BAZEL_OPTIMIZATION //tensorflow_io/... //tensorflow_io_gcs_filesystem/...

# Once build is complete, shared libraries will be available in
# `bazel-bin/tensorflow_io/core`, `bazel-bin/tensorflow_io/python/ops` and
# it is possible to run tests with `pytest`, e.g.:
sudo python3 -m pip install pytest
TFIO_DATAPATH=bazel-bin python3 -m pytest -s -v tests/test_serialization.py
센트OS 8

CentOS 8용 공유 라이브러리를 구축하는 단계는 다음을 제외하면 위의 Ubuntu 20.04와 유사합니다.

sudo yum install -y python3 python3-devel gcc gcc-c++ git unzip which make

대신 gcc/g++, git, unzip/which(bazel용) 및 python3을 설치하는 데 사용해야 합니다.

센트OS 7

CentOS 7에서는 기본 Python 및 gcc 버전이 너무 오래되어 tensorflow-io의 공유 라이브러리(.so)를 빌드할 수 없습니다. 대신 Developer Toolset 및 rh-python36에서 제공하는 gcc를 사용해야 합니다. 또한 libstdc++는 CentOS에 설치된 libstdc++와 devtoolset의 최신 gcc 버전의 불일치를 방지하기 위해 정적으로 링크되어야 합니다.

또한 파일 시스템 플러그인에 대해 정적으로 링크된 라이브러리에서 기호 중복을 방지하려면 특수 플래그 --//tensorflow_io/core:static_build Bazel에 전달해야 합니다.

다음은 bazel, devtoolset-9, rh-python36을 설치하고 공유 라이브러리를 빌드합니다.

#!/usr/bin/env bash

# Install centos-release-scl, then install gcc/g++ (devtoolset), git, and python 3
sudo yum install -y centos-release-scl
sudo yum install -y devtoolset-9 git rh-python36 make

# Install Bazel version specified in .bazelversion
curl -sSOL <a href="https://github.com/bazelbuild/bazel/releases/download/">https://github.com/bazelbuild/bazel/releases/download/</a>\\((cat .bazelversion)/bazel-\\)(cat .bazelversion)-installer-linux-x86_64.sh
sudo bash -x -e bazel-$(cat .bazelversion)-installer-linux-x86_64.sh

# Upgrade pip
scl enable rh-python36 devtoolset-9 \
    'python3 -m pip install -U pip'

# Install tensorflow and configure bazel with rh-python36
scl enable rh-python36 devtoolset-9 \
    './configure.sh'

# Add any optimization on bazel command, e.g., --compilation_mode=opt,
#   --copt=-msse4.2, --remote_cache=, etc.
# export BAZEL_OPTIMIZATION=

# Build shared libraries, notice the passing of --//tensorflow_io/core:static_build
BAZEL_LINKOPTS="-static-libstdc++ -static-libgcc" BAZEL_LINKLIBS="-lm -l%:libstdc++.a" \
  scl enable rh-python36 devtoolset-9 \
    'bazel build -s --verbose_failures $BAZEL_OPTIMIZATION --//tensorflow_io/core:static_build //tensorflow_io/...'

# Once build is complete, shared libraries will be available in
# `bazel-bin/tensorflow_io/core`, `bazel-bin/tensorflow_io/python/ops` and
# it is possible to run tests with `pytest`, e.g.:
scl enable rh-python36 devtoolset-9 \
    'python3 -m pip install pytest'

TFIO_DATAPATH=bazel-bin \
  scl enable rh-python36 devtoolset-9 \
    'python3 -m pytest -s -v tests/test_serialization.py'

도커

Python 개발의 경우 여기에 있는 참조 Dockerfile을 사용하여 소스에서 TensorFlow I/O 패키지( tensorflow-io )를 빌드할 수 있습니다. 또한 사전 구축된 개발 이미지도 사용할 수 있습니다.

# Pull (if necessary) and start the devel container
\\( docker run -it --rm --name tfio-dev --net=host -v \\){PWD}:/v -w /v tfsigio/tfio:latest-devel bash

# Inside the docker container, ./configure.sh will install TensorFlow or use existing install
(tfio-dev) root@docker-desktop:/v$ ./configure.sh

# Clean up exisiting bazel build's (if any)
(tfio-dev) root@docker-desktop:/v$ rm -rf bazel-*

# Build TensorFlow I/O C++. For compilation optimization flags, the default (-march=native)
# optimizes the generated code for your machine's CPU type.
# Reference: <a href="https://www.tensorflow.orginstall/source#configuration_options">https://www.tensorflow.orginstall/source#configuration_options</a>).

# NOTE: Based on the available resources, please change the number of job workers to:
# -j 4/8/16 to prevent bazel server terminations and resource oriented build errors.

(tfio-dev) root@docker-desktop:/v$ bazel build -j 8 --copt=-msse4.2 --copt=-mavx --compilation_mode=opt --verbose_failures --test_output=errors --crosstool_top=//third_party/toolchains/gcc7_manylinux2010:toolchain //tensorflow_io/... //tensorflow_io_gcs_filesystem/...


# Run tests with PyTest, note: some tests require launching additional containers to run (see below)
(tfio-dev) root@docker-desktop:/v$ pytest -s -v tests/
# Build the TensorFlow I/O package
(tfio-dev) root@docker-desktop:/v$ python setup.py bdist_wheel

빌드가 성공한 후 패키지 파일 dist/tensorflow_io-*.whl 생성됩니다.

파이썬 휠

다음 명령을 사용하여 bazel 빌드가 완료된 후 Python 휠을 빌드할 수 있습니다.

$ python setup.py bdist_wheel --data bazel-bin

.whl 파일은 dist 디렉터리에서 사용할 수 있습니다. bazel 바이너리 디렉토리 bazel-bin bazel-bin tensorflow_io 패키지 디렉토리 외부에 있으므로 setup.py가 필요한 공유 객체를 찾으려면 --data args와 함께 전달되어야 합니다.

또는 다음을 사용하여 소스 설치를 수행할 수 있습니다.

$ TFIO_DATAPATH=bazel-bin python -m pip install .

같은 이유로 TFIO_DATAPATH=bazel-bin 전달되었습니다.

-e 사용하여 설치하는 것은 위와 다릅니다. 그만큼

$ TFIO_DATAPATH=bazel-bin python -m pip install -e .

TFIO_DATAPATH=bazel-bin 사용해도 공유 객체를 자동으로 설치하지 않습니다. 대신, 설치 후 프로그램이 실행될 때마다 TFIO_DATAPATH=bazel-bin 전달해야 합니다.

$ TFIO_DATAPATH=bazel-bin python

>>> import tensorflow_io as tfio
>>> ...

테스트

일부 테스트는 실행하기 전에 테스트 컨테이너를 시작하거나 관련 도구의 로컬 인스턴스를 시작해야 합니다. 예를 들어, kafka, 사육사 및 스키마 레지스트리의 로컬 인스턴스를 시작하는 kafka 관련 테스트를 실행하려면 다음을 사용하십시오.

# Start the local instances of kafka, zookeeper and schema-registry
$ bash -x -e tests/test_kafka/kafka_test.sh

# Run the tests
$ TFIO_DATAPATH=bazel-bin pytest -s -vv tests/test_kafka.py

Elasticsearch 또는 MongoDB 와 같은 도구와 관련된 Datasets 테스트하려면 시스템에서 docker를 사용할 수 있어야 합니다. 이러한 시나리오에서는 다음을 사용합니다.

# Start elasticsearch within docker container
$ bash tests/test_elasticsearch/elasticsearch_test.sh start

# Run the tests
$ TFIO_DATAPATH=bazel-bin pytest -s -vv tests/test_elasticsearch.py

# Stop and remove the container
$ bash tests/test_elasticsearch/elasticsearch_test.sh stop

또한 tensorflow-io 의 일부 기능을 테스트하는 데는 데이터가 tests 디렉터리 자체에 제공되므로 추가 도구를 가동할 필요가 없습니다. 예를 들어, parquet 데이터세트와 관련된 테스트를 실행하려면 다음을 사용하세요.

# Just run the test
$ TFIO_DATAPATH=bazel-bin pytest -s -vv tests/test_parquet.py

아르 자형

테스트를 위해 R 패키지를 직접 사용할 수 있도록 여기에 참조 Dockerfile이 제공됩니다. 다음을 통해 빌드할 수 있습니다.

$ docker build -t tfio-r-dev -f R-package/scripts/Dockerfile .

컨테이너 내에서 R 세션을 시작하고 예시 Hadoop SequenceFile string.seq 에서 SequenceFileDataset 인스턴스화한 후 다음과 같이 데이터세트에서 tfdatasets 패키지가 제공하는 변환 함수를 사용할 수 있습니다.

library(tfio)
dataset <- sequence_file_dataset("R-package/tests/testthat/testdata/string.seq") %>%
    dataset_repeat(2)

sess <- tf$Session()
iterator <- make_iterator_one_shot(dataset)
next_batch <- iterator_get_next(iterator)

until_out_of_range({
  batch <- sess$run(next_batch)
  print(batch)
})