diff --git a/.clang-tidy b/.clang-tidy index 25fbff9f1a4d..b0f28e29b7c3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -17,45 +17,33 @@ # The checks defined here will be run and will display by default as warnings. Checks: > - -*, cppcoreguidelines-c-copy-assignment-signature, - cppcoreguidelines-interfaces-global-init, cppcoreguidelines-no-malloc, - cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-pro-type-const-cast, - cppcoreguidelines-pro-type-cstyle-cast, cppcoreguidelines-pro-type-member-init, - cppcoreguidelines-pro-type-static-cast-downcast, cppcoreguidelines-pro-type-union-access, - cppcoreguidelines-pro-type-vararg, cppcoreguidelines-slicing, - cppcoreguidelines-special-member-functions, clang-analyzer-security.FloatLoopCounter, - clang-analyzer-security.insecureAPI.*, clang-analyzer-core.CallAndMessage, - clang-analyzer-core.DivideZero, clang-analyzer-core.DynamicTypePropagation, - clang-analyzer-core.NonNullParamChecker, clang-analyzer-core.NullDereference, - clang-analyzer-core.StackAddressEscape, clang-analyzer-core.UndefinedBinaryOperatorResult, - clang-analyzer-core.VLASize, clang-analyzer-core.builtin.BuiltinFunctions, - clang-analyzer-core.builtin.NoReturnFunctions, clang-analyzer-core.uninitialized.ArraySubscript, - clang-analyzer-core.uninitialized.Assign, clang-analyzer-core.uninitialized.Branch, - clang-analyzer-core.uninitialized.CapturedBlockVariable, - clang-analyzer-core.uninitialized.UndefReturn, clang-analyzer-cplusplus.NewDelete, - clang-analyzer-cplusplus.NewDeleteLeaks, clang-analyzer-cplusplus.SelfAssignment, - clang-analyzer-deadcode.DeadStores, modernize-avoid-bind, modernize-deprecated-headers, - modernize-loop-convert, modernize-make-shared, modernize-pass-by-value, + -*, cppcoreguidelines-* clang-analyzer-*, modernize-*, + performance-faster-string-find, performance-for-range-copy, + performance-implicit-conversion-in-loop, performance-inefficient-algorithm, + performance-inefficient-string-concatenation, performance-trivially-destructible, + performance-inefficient-vector-operation, performance-move-const-arg, + performance-move-constructor-init, performance-noexcept-move-constructor, + performance-no-automatic-move, performance-unnecessary-copy-initialization, + performance-type-promotion-in-math-fn + +# performance checks not enabled due to segmentation fault in clang-tidy v8+: +# performance-unnecessary-value-param + +# In order to trigger an error, you must have a rule defined both in checks and in this section. +WarningsAsErrors: > + cppcoreguidelines-no-malloc, modernize-deprecated-headers, + modernize-loop-convert, modernize-make-shared, modernize-pass-by-value, modernize-make-unique, modernize-raw-string-literal, modernize-redundant-void-arg, modernize-replace-auto-ptr, modernize-replace-random-shuffle, modernize-return-braced-init-list, modernize-shrink-to-fit, modernize-unary-static-assert, modernize-use-bool-literals, modernize-use-default-member-init, modernize-use-emplace, modernize-use-equals-default, modernize-use-equals-delete, modernize-use-noexcept, modernize-use-nullptr, modernize-use-override, - modernize-use-transparent-functors, modernize-use-using, performance-* + modernize-use-transparent-functors, modernize-use-using, + performance-unnecessary-copy-initialization, performance-move-const-arg -# cppcoreguidelines checks not enabled: -# cppcoreguidelines-pro-bounds-pointer-arithmetic -# cppcoreguidelines-pro-bounds-array-to-pointer-decay -# cppcoreguidelines-pro-type-reinterpret-cast - -# modernize checks not enabled: +# modernize checks not enforced: # modernize-use-auto -# modernize-make-unique (C++14 and newer only) - -# In order to trigger an error, you must have a rule defined both in checks and in this section. -WarningsAsErrors: > - cppcoreguidelines-no-malloc, modernize-use-nullptr, performance-unnecessary-copy-initialization, - modernize-use-emplace, performance-move-const-arg +# modernize-avoid-bind # Todo: define a better regex match that includes most project headers, but excludes third party # code. diff --git a/.codecov.yml b/.codecov.yml index 70037e6483ff..5253ec7b40f4 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -11,11 +11,6 @@ coverage: round: down range: "70...100" - status: - project: yes - patch: yes - changes: no - parsers: gcov: branch_detection: diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7a0115d36433..b34ee8b7b7e7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: '' -labels: 'Bug' +labels: 'Bug, needs triage' assignees: '' --- diff --git a/3rdparty/nvidia_cub b/3rdparty/nvidia_cub index c3cceac115c0..0158fa19f286 160000 --- a/3rdparty/nvidia_cub +++ b/3rdparty/nvidia_cub @@ -1 +1 @@ -Subproject commit c3cceac115c072fb63df1836ff46d8c60d9eb304 +Subproject commit 0158fa19f28619886232defd412433974af89611 diff --git a/CMakeLists.txt b/CMakeLists.txt index 688dd42c54fe..e302ac7b865c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,6 @@ option(USE_JEMALLOC "Build with Jemalloc support" OFF) option(USE_LIBJPEG_TURBO "Use libjpeg-turbo" OFF) option(USE_DIST_KVSTORE "Build with DIST_KVSTORE support" OFF) option(USE_PLUGINS_WARPCTC "Use WARPCTC Plugins" OFF) -option(USE_PLUGIN_CAFFE "Use Caffe Plugin" OFF) option(USE_CPP_PACKAGE "Build C++ Package" OFF) option(USE_MXNET_LIB_NAMING "Use MXNet library naming conventions." ON) option(USE_GPROF "Compile with gprof (profiling) flag" OFF) @@ -148,6 +147,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Distribution" AND UNIX AND NOT APPLE) # Enforce DT_PATH instead of DT_RUNPATH set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--disable-new-dtags") set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags") + set(Protobuf_USE_STATIC_LIBS ON) endif() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/upstream;${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules;${CMAKE_MODULE_PATH}") @@ -276,6 +276,7 @@ if(USE_MKLDNN) include_directories(${PROJECT_BINARY_DIR}/3rdparty/mkldnn/include) add_definitions(-DMXNET_USE_MKLDNN=1) list(APPEND mxnet_LINKER_LIBS dnnl) + set_target_properties(dnnl PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency endif() # Allow Cuda compiles outside of src tree to find things in 'src' and 'include' @@ -299,7 +300,6 @@ foreach(var ${C_CXX_INCLUDE_DIRECTORIES}) endforeach() include_directories("include") -include_directories("3rdparty/nvidia_cub") include_directories("3rdparty/tvm/nnvm/include") include_directories("3rdparty/tvm/include") include_directories("3rdparty/dmlc-core/include") @@ -407,6 +407,7 @@ if(USE_OPENMP) AND NOT CMAKE_CROSSCOMPILING) load_omp() list(APPEND mxnet_LINKER_LIBS omp) + set_target_properties(omp PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency if(UNIX) list(APPEND mxnet_LINKER_LIBS pthread) endif() @@ -464,6 +465,8 @@ set(GTEST_MAIN_LIBRARY gtest_main) set(GTEST_LIBRARY gtest) add_subdirectory(${GTEST_ROOT}) +set_target_properties(gtest PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency +set_target_properties(gtest_main PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency find_package(GTest REQUIRED) # cudnn detection @@ -480,6 +483,7 @@ endif() if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dmlc-core/cmake) add_subdirectory("3rdparty/dmlc-core") + set_target_properties(dmlc PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency endif() FILE(GLOB_RECURSE SOURCE "src/*.cc" "src/*.h" "include/*.h") @@ -494,7 +498,9 @@ FILE(GLOB_RECURSE NNVMSOURCE 3rdparty/tvm/nnvm/src/core/*.h 3rdparty/tvm/nnvm/src/pass/*.h 3rdparty/tvm/nnvm/include/*.h) -list(APPEND SOURCE ${NNVMSOURCE}) +add_library(nnvm OBJECT ${NNVMSOURCE}) +set_target_properties(nnvm PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency +list(APPEND SOURCE $) # add source group FILE(GLOB_RECURSE GROUP_SOURCE "src/*.cc" "3rdparty/tvm/nnvm/*.cc" "plugin/*.cc") @@ -521,39 +527,6 @@ if(USE_OPERATOR_TUNING AND USE_OPENMP) add_definitions(-DMXNET_USE_OPERATOR_TUNING=1) endif() -if(USE_PLUGIN_CAFFE) - if(NOT USE_CUDA) - set(CPU_ONLY ON) - add_definitions(-DCPU_ONLY=1) - endif() - if(NOT DEFINED CAFFE_PATH) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/caffe) - set(CAFFE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/caffe) - else() - set(CAFFE_PATH $ENV{CAFFE_PATH}) - endif() - endif() - list(APPEND CMAKE_MODULE_PATH ${CAFFE_PATH}/cmake) - include_directories(${CAFFE_PATH}/include) - include_directories(${CAFFE_PATH}/build/src) - include_directories(${CMAKE_BINARY_DIR}/caffe/include) - link_directories(${CAFFE_PATH}/build/lib) - if(NOT DEFINED CAFFE_PATH) - message(FATAL_ERROR "Please set CAFFE_PATH to point to the caffe source installation") - endif() - FILE(GLOB_RECURSE PLUGINS_SOURCE "plugin/caffe/*.cc" "plugin/caffe/*.h") - FILE(GLOB_RECURSE PLUGINS_CUSRC "plugin/caffe/*.cu") - list(APPEND SOURCE ${PLUGINS_SOURCE}) - list(APPEND CUDA ${PLUGINS_CUSRC}) - include_directories(${CMAKE_BINARY_DIR}/include) - add_definitions(-DMXNET_USE_CAFFE=1) - list(APPEND mxnet_LINKER_LIBS - protobuf boost_system boost_thread boost_filesystem - gflags glog caffe - ${Caffe_LINKER_LIBS} -) -endif() - if (NOT (EXTRA_OPERATORS STREQUAL "")) mxnet_source_group("Extra" GLOB_RECURSE "${EXTRA_OPERATORS}/*.cc") mxnet_source_group("Extra\\Cuda" GLOB_RECURSE "${EXTRA_OPERATORS}/*.cu") @@ -640,14 +613,10 @@ if(USE_CUDA) link_directories(${CUDAToolkit_LIBRARY_DIR}) endif() -# unsupported: if caffe is a subdirectory of mxnet, load its CMakeLists.txt as well -if(USE_PLUGIN_CAFFE) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/caffe) - add_subdirectory(caffe) - endif() +if(CUDAToolkit_VERSION_MAJOR LESS "11") + include_directories("3rdparty/nvidia_cub") endif() - if(MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /EHsc") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHsc /Gy") @@ -674,7 +643,6 @@ if(UNIX) endif() target_link_libraries(mxnet PUBLIC mshadow) target_link_libraries(mxnet PUBLIC ${CMAKE_DL_LIBS}) - target_compile_definitions(mxnet PUBLIC DMLC_LOG_FATAL_THROW=$) if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") target_compile_options(mxnet PRIVATE "$<$:-Werror>") # Ignore erroneous compiler warnings: @@ -701,7 +669,6 @@ elseif(MSVC) foreach(arch ${arch_code_list}) add_library(mxnet_${arch} SHARED ${SOURCE}) target_link_libraries(mxnet_${arch} PUBLIC mshadow) - target_compile_definitions(mxnet_${arch} PUBLIC DMLC_LOG_FATAL_THROW=$) target_compile_options( mxnet_${arch} PRIVATE @@ -737,10 +704,10 @@ elseif(MSVC) endif(USE_SPLIT_ARCH_DLL) else() add_library(mxnet SHARED ${SOURCE}) - target_compile_definitions(mxnet PUBLIC DMLC_LOG_FATAL_THROW=$) target_link_libraries(mxnet PUBLIC mshadow) endif() endif() +target_compile_definitions(mxnet PUBLIC DMLC_LOG_FATAL_THROW=$) # extension libraries (custom operators, custom subgraphs) are built by default add_library(customop_lib SHARED ${CMAKE_CURRENT_SOURCE_DIR}/example/extensions/lib_custom_op/gemm_lib.cc) @@ -782,6 +749,7 @@ if(USE_DIST_KVSTORE) add_subdirectory("3rdparty/ps-lite") add_definitions(-DMXNET_USE_DIST_KVSTORE) list(APPEND mxnet_LINKER_LIBS pslite) + set_target_properties(pslite PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency endif() if(USE_MKLDNN) @@ -796,6 +764,9 @@ function(BuildTVMOP) # scope the variables in BuildTVM.cmake to avoid conflict include(cmake/BuildTVM.cmake) add_subdirectory("3rdparty/tvm") + set_target_properties(tvm PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency + set_target_properties(tvm_topi PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency + set_target_properties(tvm_runtime PROPERTIES CXX_CLANG_TIDY "") # don't lint 3rdparty dependency endfunction() if(USE_TVM_OP) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f63b2412077b..4146d45b5c9d 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -254,6 +254,7 @@ List of Contributors * [Connor Goggins](https://github.com/connorgoggins) * [Wei Chu](https://github.com/waytrue17) * [Yang Shi](https://github.com/ys2843) +* [Joe Evans](https://github.com/josephevans) Label Bot --------- diff --git a/Makefile b/Makefile deleted file mode 100644 index 0bf856f677bb..000000000000 --- a/Makefile +++ /dev/null @@ -1,768 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -ROOTDIR = $(CURDIR) -TPARTYDIR = $(ROOTDIR)/3rdparty - -ifeq ($(OS),Windows_NT) - UNAME_S := Windows -else - UNAME_S := $(shell uname -s) - UNAME_P := $(shell uname -p) -endif - -ifndef config -ifdef CXXNET_CONFIG - config = $(CXXNET_CONFIG) -else ifneq ("$(wildcard ./config.mk)","") - config = config.mk -else - config = make/config.mk -endif -endif - -ifndef DMLC_CORE - DMLC_CORE = $(TPARTYDIR)/dmlc-core -endif -CORE_INC = $(wildcard $(DMLC_CORE)/include/*/*.h) - -ifndef NNVM_PATH - NNVM_PATH = $(TPARTYDIR)/tvm/nnvm -endif - -ifndef DLPACK_PATH - DLPACK_PATH = $(ROOTDIR)/3rdparty/dlpack -endif - -ifndef TVM_PATH - TVM_PATH = $(TPARTYDIR)/tvm -endif - -ifndef LLVM_PATH - LLVM_PATH = $(TVM_PATH)/build/llvm -endif - -ifneq ($(USE_OPENMP), 1) - export NO_OPENMP = 1 -endif - -# use customized config file -include $(config) - -ifndef USE_MKLDNN -ifneq ($(UNAME_S), Darwin) -ifneq ($(UNAME_S), Windows) -ifeq ($(UNAME_P), x86_64) - USE_MKLDNN=1 -endif -endif -endif -endif - -ifeq ($(USE_MKL2017), 1) -$(warning "USE_MKL2017 is deprecated. We will switch to USE_MKLDNN.") - USE_MKLDNN=1 -endif - -ifeq ($(USE_MKLDNN), 1) - MKLDNNROOT = $(ROOTDIR)/3rdparty/mkldnn/build/install -endif - -include $(TPARTYDIR)/mshadow/make/mshadow.mk -include $(DMLC_CORE)/make/dmlc.mk - -# all tge possible warning tread -WARNFLAGS= -Wall -Wsign-compare -CFLAGS = -DMSHADOW_FORCE_STREAM $(WARNFLAGS) -# C++ standard -CFLAGS+= -DDMLC_USE_CXX11=1 -DDMLC_USE_CXX11=1 -DDMLC_USE_CXX14=1 -# use old thread local implementation in DMLC-CORE -CFLAGS += -DDMLC_MODERN_THREAD_LOCAL=0 -# disable stack trace in exception by default. -CFLAGS += -DDMLC_LOG_STACK_TRACE_SIZE=0 -CFLAGS += -DDMLC_LOG_FATAL_THROW=1 - -ifeq ($(DEV), 1) - # Excluded from Werror: - # 1) variables used in '#pragma omp parallel' are considered unused - CFLAGS += -g -Werror -Wno-error=unused-variable -Wno-error=maybe-uninitialized -Wno-error=unused-function - NVCCFLAGS += -Werror cross-execution-space-call -endif - -# CFLAGS for debug -ifeq ($(DEBUG), 1) - CFLAGS += -g -O0 -D_GLIBCXX_ASSERTIONS -else - CFLAGS += -O3 -DNDEBUG=1 -endif -CFLAGS += -I$(TPARTYDIR)/mshadow/ -I$(TPARTYDIR)/dmlc-core/include -fPIC -I$(NNVM_PATH)/include -I$(DLPACK_PATH)/include -I$(TPARTYDIR)/tvm/include -Iinclude $(MSHADOW_CFLAGS) -LDFLAGS = -pthread -ldl $(MSHADOW_LDFLAGS) $(DMLC_LDFLAGS) - -# please note that when you enable this, you might run into an linker not being able to work properly due to large code injection. -# you can find more information here https://github.com/apache/incubator-mxnet/issues/15971 -ifeq ($(ENABLE_TESTCOVERAGE), 1) - CFLAGS += --coverage - LDFLAGS += --coverage -endif - -ifeq ($(USE_NVTX), 1) - CFLAGS += -DMXNET_USE_NVTX=1 - LDFLAGS += -lnvToolsExt -endif - -ifeq ($(USE_TENSORRT), 1) - CFLAGS += -I$(ROOTDIR) -I$(TPARTYDIR) -DONNX_NAMESPACE=$(ONNX_NAMESPACE) -DMXNET_USE_TENSORRT=1 - LDFLAGS += -lprotobuf -pthread -lonnx -lonnx_proto -lnvonnxparser -lnvonnxparser_runtime -lnvinfer -lnvinfer_plugin -endif -# -L/usr/local/lib - -ifeq ($(DEBUG), 1) - NVCCFLAGS += -std=c++14 -Xcompiler -D_FORCE_INLINES -g -G -O0 -ccbin $(CXX) $(MSHADOW_NVCCFLAGS) -else - NVCCFLAGS += -std=c++14 -Xcompiler -D_FORCE_INLINES -O3 -ccbin $(CXX) $(MSHADOW_NVCCFLAGS) -endif - -# CFLAGS for segfault logger -ifeq ($(USE_SIGNAL_HANDLER), 1) - CFLAGS += -DMXNET_USE_SIGNAL_HANDLER=1 -endif - -# Caffe Plugin -ifdef CAFFE_PATH - CFLAGS += -DMXNET_USE_CAFFE=1 -endif - -ifndef LINT_LANG - LINT_LANG = "all" -endif - -ifeq ($(USE_MKLDNN), 1) - CFLAGS += -DMXNET_USE_MKLDNN=1 - CFLAGS += -I$(ROOTDIR)/src/operator/nn/mkldnn/ - CFLAGS += -I$(MKLDNNROOT)/include - LIB_DEP += $(MKLDNNROOT)/lib/libdnnl.a -endif - -# setup opencv -ifeq ($(USE_OPENCV), 1) - CFLAGS += -DMXNET_USE_OPENCV=1 - ifneq ($(filter-out NONE, $(USE_OPENCV_INC_PATH)),) - CFLAGS += -I$(USE_OPENCV_INC_PATH)/include - ifeq ($(filter-out NONE, $(USE_OPENCV_LIB_PATH)),) -$(error Please add the path of OpenCV shared library path into `USE_OPENCV_LIB_PATH`, when `USE_OPENCV_INC_PATH` is not NONE) - endif - LDFLAGS += -L$(USE_OPENCV_LIB_PATH) - ifneq ($(wildcard $(USE_OPENCV_LIB_PATH)/libopencv_imgcodecs.*),) - LDFLAGS += -lopencv_imgcodecs - endif - ifneq ($(wildcard $(USE_OPENCV_LIB_PATH)/libopencv_highgui.*),) - LDFLAGS += -lopencv_highgui - endif - else - ifeq ("$(shell pkg-config --exists opencv4; echo $$?)", "0") - OPENCV_LIB = opencv4 - else - OPENCV_LIB = opencv - endif - CFLAGS += $(shell pkg-config --cflags $(OPENCV_LIB)) - LDFLAGS += $(shell pkg-config --libs-only-L $(OPENCV_LIB)) - LDFLAGS += $(filter -lopencv_imgcodecs -lopencv_highgui, $(shell pkg-config --libs-only-l $(OPENCV_LIB))) - endif - LDFLAGS += -lopencv_imgproc -lopencv_core - BIN += bin/im2rec -else - CFLAGS += -DMXNET_USE_OPENCV=0 -endif - -ifeq ($(USE_OPENMP), 1) - CFLAGS += -fopenmp - CFLAGS += -DMXNET_USE_OPENMP=1 -endif - -ifeq ($(USE_NNPACK), 1) - CFLAGS += -DMXNET_USE_NNPACK=1 - LDFLAGS += -lnnpack -endif - -ifeq ($(USE_OPERATOR_TUNING), 1) - CFLAGS += -DMXNET_USE_OPERATOR_TUNING=1 -endif - -ifeq ($(USE_INT64_TENSOR_SIZE), 1) - CFLAGS += -DMSHADOW_INT64_TENSOR_SIZE=1 -else - CFLAGS += -DMSHADOW_INT64_TENSOR_SIZE=0 -endif -# verify existence of separate lapack library when using blas/openblas/atlas -# switch off lapack support in case it can't be found -# issue covered with this -# - for Ubuntu 14.04 or lower, lapack is not automatically installed with openblas -# - for Ubuntu, installing atlas will not automatically install the atlas provided lapack library -# - for rhel7.2, try installing the package `lapack-static` via yum will dismiss this warning. -# silently switching lapack off instead of letting the build fail because of backward compatibility -ifeq ($(USE_LAPACK), 1) -ifeq ($(USE_BLAS),$(filter $(USE_BLAS),blas openblas atlas mkl)) -ifeq (,$(wildcard $(USE_LAPACK_PATH)/liblapack.a)) -ifeq (,$(wildcard $(USE_LAPACK_PATH)/liblapack.so)) -ifeq (,$(wildcard $(USE_LAPACK_PATH)/liblapack.dylib)) -ifeq (,$(wildcard /lib/liblapack.a)) -ifeq (,$(wildcard /lib/liblapack.so)) -ifeq (,$(wildcard /usr/lib/liblapack.a)) -ifeq (,$(wildcard /usr/lib/liblapack.so)) -ifeq (,$(wildcard /usr/lib/x86_64-linux-gnu/liblapack.a)) -ifeq (,$(wildcard /usr/lib/x86_64-linux-gnu/liblapack.so)) -ifeq (,$(wildcard /usr/lib/liblapack.dylib)) -ifeq (,$(wildcard /usr/lib64/liblapack.a)) -ifeq (,$(wildcard /usr/lib64/liblapack.so)) - USE_LAPACK = 0 - $(warning "USE_LAPACK disabled because libraries were not found") -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif -endif - -# lapack settings. -ifeq ($(USE_LAPACK), 1) - ifneq ($(USE_LAPACK_PATH), ) - LDFLAGS += -L$(USE_LAPACK_PATH) - endif - ifeq ($(USE_BLAS),$(filter $(USE_BLAS),blas openblas atlas mkl)) - LDFLAGS += -llapack - endif - CFLAGS += -DMXNET_USE_LAPACK -endif - -ifeq ($(USE_CUDNN), 1) - CFLAGS += -DMSHADOW_USE_CUDNN=1 - LDFLAGS += -lcudnn -endif - -ifeq ($(USE_BLAS), openblas) - CFLAGS += -DMXNET_USE_BLAS_OPEN=1 -else ifeq ($(USE_BLAS), atlas) - CFLAGS += -DMXNET_USE_BLAS_ATLAS=1 -else ifeq ($(USE_BLAS), mkl) - CFLAGS += -DMXNET_USE_BLAS_MKL=1 -else ifeq ($(USE_BLAS), apple) - CFLAGS += -DMXNET_USE_BLAS_APPLE=1 -endif - -# whether to use F16C instruction set extension for fast fp16 compute on CPU -# if cross compiling you may want to explicitly turn it off if target system does not support it -ifndef USE_F16C - ifneq ($(OS),Windows_NT) - detected_OS := $(shell uname -s) - ifeq ($(detected_OS),Darwin) - F16C_SUPP = $(shell sysctl -a | grep machdep.cpu.features | grep F16C) - endif - ifeq ($(detected_OS),Linux) - F16C_SUPP = $(shell cat /proc/cpuinfo | grep flags | grep f16c) - endif - ifneq ($(strip $(F16C_SUPP)),) - USE_F16C=1 - else - USE_F16C=0 - endif - endif - # if OS is Windows, check if your processor and compiler support F16C architecture. - # One way to check if processor supports it is to download the tool - # https://docs.microsoft.com/en-us/sysinternals/downloads/coreinfo. - # If coreinfo -c shows F16C and compiler supports it, - # then you can set USE_F16C=1 explicitly to leverage that capability" -endif - -# gperftools malloc library (tcmalloc) -ifeq ($(USE_GPERFTOOLS), 1) -FIND_LIBFILEEXT=so -ifeq ($(USE_GPERFTOOLS_STATIC), 1) -FIND_LIBFILEEXT=a -endif -FIND_LIBFILE=$(wildcard $(USE_GPERFTOOLS_PATH)/libtcmalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /lib/libtcmalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/lib/libtcmalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/local/lib/libtcmalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/lib64/libtcmalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) - USE_GPERFTOOLS=0 -endif -endif -endif -endif -endif -ifeq ($(USE_GPERFTOOLS), 1) - CFLAGS += -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free - LDFLAGS += $(FIND_LIBFILE) -endif - -# jemalloc malloc library (if not using gperftools) -else -ifeq ($(USE_JEMALLOC), 1) -FIND_LIBFILEEXT=so -ifeq ($(USE_JEMALLOC_STATIC), 1) -FIND_LIBFILEEXT=a -endif -FIND_LIBFILE=$(wildcard $(USE_JEMALLOC_PATH)/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /lib/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/lib/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/local/lib/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/lib/x86_64-linux-gnu/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) -FIND_LIBFILE=$(wildcard /usr/lib64/libjemalloc.$(FIND_LIBFILEEXT)) -ifeq (,$(FIND_LIBFILE)) - USE_JEMALLOC=0 -endif -endif -endif -endif -endif -endif -ifeq ($(USE_JEMALLOC), 1) - CFLAGS += -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc \ - -fno-builtin-free -DUSE_JEMALLOC - LDFLAGS += $(FIND_LIBFILE) -endif -endif -endif - -# If not using tcmalloc or jemalloc, print a warning (user should consider installing) -ifneq ($(USE_GPERFTOOLS), 1) -ifneq ($(USE_JEMALLOC), 1) -$(warning WARNING: Significant performance increases can be achieved by installing and \ -enabling gperftools or jemalloc development packages) -endif -endif - -ifeq ($(USE_THREADED_ENGINE), 1) - CFLAGS += -DMXNET_USE_THREADED_ENGINE -endif - -ifneq ($(ADD_CFLAGS), NONE) - CFLAGS += $(ADD_CFLAGS) -endif - -ifneq ($(ADD_LDFLAGS), NONE) - LDFLAGS += $(ADD_LDFLAGS) -endif - -ifeq ($(NVCC), NONE) - # If NVCC has not been manually defined, use the CUDA_PATH bin dir. - ifneq ($(USE_CUDA_PATH), NONE) - NVCC=$(USE_CUDA_PATH)/bin/nvcc - endif -endif - -# Guard against displaying nvcc info messages to users not using CUDA. -ifeq ($(USE_CUDA), 1) - # Get AR version, compare with expected ar version and find bigger and smaller version of the two - AR_VERSION := $(shell ar --version | egrep -o "([0-9]{1,}\.)+[0-9]{1,}") - EXPECTED_AR_VERSION := $(shell echo "2.27") - LARGE_VERSION := $(shell printf '%s\n' "$(AR_VERSION)" "$(EXPECTED_AR_VERSION)" | sort -V | tail -n 1) - SMALL_VERSION := $(shell printf '%s\n' "$(AR_VERSION)" "$(EXPECTED_AR_VERSION)" | sort -V | head -n 1) - - # If NVCC is not at the location specified, use CUDA_PATH instead. - ifeq ("$(wildcard $(NVCC))","") - ifneq ($(USE_CUDA_PATH), NONE) - NVCC=$(USE_CUDA_PATH)/bin/nvcc - -# if larger version is the expected one and larger != smaller -# this means ar version is less than expected version and user needs to be warned -ifeq ($(LARGE_VERSION), $(EXPECTED_AR_VERSION)) -ifneq ($(LARGE_VERSION), $(SMALL_VERSION)) -define n - - -endef - -$(warning WARNING: Archive utility: ar version being used is less than 2.27.0. $n \ - Note that with USE_CUDA=1 flag and USE_CUDNN=1 this is known to cause problems. $n \ - For more info see: https://github.com/apache/incubator-mxnet/issues/15084) -$(shell sleep 5) -endif -endif -$(info INFO: nvcc was not found on your path) -$(info INFO: Using $(NVCC) as nvcc path) - else -$(warning WARNING: could not find nvcc compiler, the specified path was: $(NVCC)) - endif - endif -endif - -# Sets 'CUDA_ARCH', which determines the GPU architectures supported -# by the compiled kernels. Users can edit the KNOWN_CUDA_ARCHS list below -# to remove archs they don't wish to support to speed compilation, or they can -# pre-set the CUDA_ARCH args in config.mk to a non-null value for full control. -# -# For archs in this list, nvcc will create a fat-binary that will include -# the binaries (SASS) for all architectures supported by the installed version -# of the cuda toolkit, plus the assembly (PTX) for the most recent such architecture. -# If these kernels are then run on a newer-architecture GPU, the binary will -# be JIT-compiled by the updated driver from the included PTX. -ifeq ($(USE_CUDA), 1) -ifeq ($(CUDA_ARCH),) - KNOWN_CUDA_ARCHS := 30 35 50 52 60 61 70 75 - # Run nvcc on a zero-length file to check architecture-level support. - # Create args to include SASS in the fat binary for supported levels. - CUDA_ARCH := $(foreach arch,$(KNOWN_CUDA_ARCHS), \ - $(shell $(NVCC) -arch=sm_$(arch) -E --x cu /dev/null >/dev/null 2>&1 && \ - echo -gencode arch=compute_$(arch),code=sm_$(arch))) - # Convert a trailing "code=sm_NN" to "code=[sm_NN,compute_NN]" to also - # include the PTX of the most recent arch in the fat-binaries for - # forward compatibility with newer GPUs. - CUDA_ARCH := $(shell echo $(CUDA_ARCH) | sed 's/sm_\([0-9]*\)$$/[sm_\1,compute_\1]/') - # Add fat binary compression if supported by nvcc. - COMPRESS := --fatbin-options -compress-all - CUDA_ARCH += $(shell $(NVCC) -cuda $(COMPRESS) --x cu /dev/null -o /dev/null >/dev/null 2>&1 && \ - echo $(COMPRESS)) -endif -$(info Running CUDA_ARCH: $(CUDA_ARCH)) -endif - -# ps-lite -PS_PATH=$(ROOTDIR)/3rdparty/ps-lite -DEPS_PATH=$(shell pwd)/deps -include $(PS_PATH)/make/ps.mk -ifeq ($(USE_DIST_KVSTORE), 1) - CFLAGS += -DMXNET_USE_DIST_KVSTORE -I$(PS_PATH)/include -I$(DEPS_PATH)/include - LIB_DEP += $(PS_PATH)/build/libps.a - LDFLAGS += $(PS_LDFLAGS_A) -endif - -.PHONY: clean all extra-packages test lint clean_all roxygen\ - cython3 cython cyclean - -all: lib/libmxnet.a lib/libmxnet.so $(BIN) extra-packages extension_libs - -SRC = $(wildcard src/*/*/*/*/*.cc src/*/*/*/*.cc src/*/*/*.cc src/*/*.cc src/*.cc) -OBJ = $(patsubst %.cc, build/%.o, $(SRC)) -CUSRC = $(wildcard src/*/*/*/*.cu src/*/*/*/*.cu src/*/*/*.cu src/*/*.cu src/*.cu) -CUOBJ = $(patsubst %.cu, build/%_gpu.o, $(CUSRC)) - -ifeq ($(USE_TVM_OP), 1) -LIB_DEP += lib/libtvm_runtime.so lib/libtvmop.so -CFLAGS += -I$(TVM_PATH)/include -DMXNET_USE_TVM_OP=1 -LDFLAGS += -L$(ROOTDIR)/lib -ltvm_runtime -Wl,-rpath,'$${ORIGIN}' - -TVM_USE_CUDA := OFF -ifeq ($(USE_CUDA), 1) - TVM_USE_CUDA := ON - ifneq ($(USE_CUDA_PATH), NONE) - TVM_USE_CUDA := $(USE_CUDA_PATH) - endif -endif -endif - -# extra operators -ifneq ($(EXTRA_OPERATORS),) - EXTRA_SRC = $(wildcard $(patsubst %, %/*.cc, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.cc, $(EXTRA_OPERATORS))) - EXTRA_OBJ = $(patsubst %.cc, %.o, $(EXTRA_SRC)) - EXTRA_CUSRC = $(wildcard $(patsubst %, %/*.cu, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.cu, $(EXTRA_OPERATORS))) - EXTRA_CUOBJ = $(patsubst %.cu, %_gpu.o, $(EXTRA_CUSRC)) -else - EXTRA_SRC = - EXTRA_OBJ = - EXTRA_CUSRC = - EXTRA_CUOBJ = -endif - -# plugin -PLUGIN_OBJ = -PLUGIN_CUOBJ = -include $(MXNET_PLUGINS) - -ifneq ($(UNAME_S), Windows) - ifeq ($(UNAME_S), Darwin) - WHOLE_ARCH= -all_load - NO_WHOLE_ARCH= -noall_load - else - WHOLE_ARCH= --whole-archive - NO_WHOLE_ARCH= --no-whole-archive - endif -endif - -# all dep -LIB_DEP += $(DMLC_CORE)/libdmlc.a $(NNVM_PATH)/lib/libnnvm.a -ALL_DEP = $(OBJ) $(EXTRA_OBJ) $(PLUGIN_OBJ) $(LIB_DEP) - -ifeq ($(USE_CUDA), 1) - CFLAGS += -I$(ROOTDIR)/3rdparty/nvidia_cub - ALL_DEP += $(CUOBJ) $(EXTRA_CUOBJ) $(PLUGIN_CUOBJ) - LDFLAGS += -lcufft - ifeq ($(ENABLE_CUDA_RTC), 1) - LDFLAGS += -lcuda -lnvrtc - CFLAGS += -DMXNET_ENABLE_CUDA_RTC=1 - endif - # Make sure to add stubs as fallback in order to be able to build - # without full CUDA install (especially if run without nvidia-docker) - LDFLAGS += -L/usr/local/cuda/lib64/stubs - ifeq ($(USE_NVML), 1) - LDFLAGS += -lnvidia-ml - CFLAGS += -DMXNET_USE_NVML=1 - else - CFLAGS += -DMXNET_USE_NVML=0 - endif - ifeq ($(USE_NCCL), 1) - ifneq ($(USE_NCCL_PATH), NONE) - CFLAGS += -I$(USE_NCCL_PATH)/include - LDFLAGS += -L$(USE_NCCL_PATH)/lib - endif - ifdef USE_SYSTEM_CUDA - LDFLAGS += -lnccl_static - else - LDFLAGS += -lnccl - endif - CFLAGS += -DMXNET_USE_NCCL=1 - else - CFLAGS += -DMXNET_USE_NCCL=0 - endif -else - CFLAGS += -DMXNET_USE_NVML=0 - CFLAGS += -DMXNET_USE_NCCL=0 -endif - -ifeq ($(USE_LIBJPEG_TURBO), 1) - ifneq ($(USE_LIBJPEG_TURBO_PATH), NONE) - CFLAGS += -I$(USE_LIBJPEG_TURBO_PATH)/include - LDFLAGS += -L$(USE_LIBJPEG_TURBO_PATH)/lib - endif - LDFLAGS += -lturbojpeg - CFLAGS += -DMXNET_USE_LIBJPEG_TURBO=1 -else - CFLAGS += -DMXNET_USE_LIBJPEG_TURBO=0 -endif - -ifeq ($(CI), 1) - MAVEN_ARGS := -B -endif - -# For quick compile test, used smaller subset -ALLX_DEP= $(ALL_DEP) - -build/src/%.o: src/%.cc | mkldnn - @mkdir -p $(@D) - $(CXX) -std=c++17 -c $(CFLAGS) -MMD -c $< -o $@ - -build/src/%_gpu.o: src/%.cu | mkldnn - @mkdir -p $(@D) - $(NVCC) $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS)" --generate-dependencies -MT build/src/$*_gpu.o $< >build/src/$*_gpu.d - $(NVCC) -c -o $@ $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS)" $< - -# A nvcc bug cause it to generate "generic/xxx.h" dependencies from torch headers. -# Use CXX to generate dependency instead. -build/plugin/%_gpu.o: plugin/%.cu - @mkdir -p $(@D) - $(CXX) -std=c++17 $(CFLAGS) -MM -MT build/plugin/$*_gpu.o $< >build/plugin/$*_gpu.d - $(NVCC) -c -o $@ $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS)" $< - -build/plugin/%.o: plugin/%.cc | mkldnn - @mkdir -p $(@D) - $(CXX) -std=c++17 -c $(CFLAGS) -MMD -c $< -o $@ - -%_gpu.o: %.cu - @mkdir -p $(@D) - $(NVCC) $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS) -Isrc/operator" --generate-dependencies -MT $*_gpu.o $< >$*_gpu.d - $(NVCC) -c -o $@ $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS) -Isrc/operator" $< - -%.o: %.cc $(CORE_INC) - @mkdir -p $(@D) - $(CXX) -std=c++17 -c $(CFLAGS) -MMD -Isrc/operator -c $< -o $@ - -# Set install path for libmxnet.so on Mac OS -ifeq ($(UNAME_S), Darwin) - LDFLAGS += -Wl,-install_name,@rpath/libmxnet.so -endif - -# NOTE: to statically link libmxnet.a we need the option -# --Wl,--whole-archive -lmxnet --Wl,--no-whole-archive -lib/libmxnet.a: $(ALLX_DEP) - @mkdir -p $(@D) - ar crv $@ $(filter %.o, $?) - -lib/libmxnet.so: $(ALLX_DEP) - @mkdir -p $(@D) - $(CXX) $(CFLAGS) -shared -o $@ $(filter-out %libnnvm.a, $(filter %.o %.a, $^)) $(LDFLAGS) \ - -Wl,${WHOLE_ARCH} $(filter %libnnvm.a, $^) -Wl,${NO_WHOLE_ARCH} - -$(PS_PATH)/build/libps.a: PSLITE - -PSLITE: - $(MAKE) CXX="$(CXX)" DEPS_PATH="$(DEPS_PATH)" -C $(PS_PATH) ps - -$(DMLC_CORE)/libdmlc.a: DMLCCORE - -DMLCCORE: - + cd $(DMLC_CORE); $(MAKE) libdmlc.a USE_SSE=$(USE_SSE) config=$(ROOTDIR)/$(config); cd $(ROOTDIR) - -lib/libtvm_runtime.so: - echo "Compile TVM" - @mkdir -p $(@D) - [ -e $(LLVM_PATH)/bin/llvm-config ] || sh $(ROOTDIR)/contrib/tvmop/prepare_tvm.sh; \ - cd $(TVM_PATH)/build; \ - cmake -DUSE_LLVM="$(LLVM_PATH)/bin/llvm-config" \ - -DUSE_SORT=OFF -DUSE_CUDA=$(TVM_USE_CUDA) -DUSE_CUDNN=OFF -DUSE_OPENMP=ON ..; \ - $(MAKE) VERBOSE=1; \ - mkdir -p $(ROOTDIR)/lib; \ - cp $(TVM_PATH)/build/libtvm_runtime.so $(ROOTDIR)/lib/libtvm_runtime.so; \ - ls $(ROOTDIR)/lib; \ - cd $(ROOTDIR) - -TVM_OP_COMPILE_OPTIONS = -o $(ROOTDIR)/lib --config $(ROOTDIR)/lib/tvmop.conf -ifneq ($(CUDA_ARCH),) - TVM_OP_COMPILE_OPTIONS += --cuda-arch "$(CUDA_ARCH)" -endif -lib/libtvmop.so: lib/libtvm_runtime.so $(wildcard contrib/tvmop/*/*.py contrib/tvmop/*.py) - echo "Compile TVM operators" - @mkdir -p $(@D) - PYTHONPATH=$(TVM_PATH)/python:$(TVM_PATH)/topi/python:$(ROOTDIR)/contrib \ - LD_LIBRARY_PATH=$(ROOTDIR)/lib \ - python3 $(ROOTDIR)/contrib/tvmop/compile.py $(TVM_OP_COMPILE_OPTIONS) - -NNVM_INC = $(wildcard $(NNVM_PATH)/include/*/*.h) -NNVM_SRC = $(wildcard $(NNVM_PATH)/src/*/*/*.cc $(NNVM_PATH)/src/*/*.cc $(NNVM_PATH)/src/*.cc) -$(NNVM_PATH)/lib/libnnvm.a: $(NNVM_INC) $(NNVM_SRC) - + cd $(NNVM_PATH); $(MAKE) lib/libnnvm.a DMLC_CORE_PATH=$(DMLC_CORE); cd $(ROOTDIR) - -bin/im2rec: tools/im2rec.cc $(ALLX_DEP) - -$(BIN) : - @mkdir -p $(@D) - $(CXX) $(CFLAGS) -std=c++17 -o $@ $(filter %.cpp %.o %.c %.a %.cc, $^) $(LDFLAGS) - -include mkldnn.mk -include tests/cpp/unittest.mk - -extra-packages: $(EXTRA_PACKAGES) - -test: $(TEST) - -lint: cpplint pylint - -cpplint: - 3rdparty/dmlc-core/scripts/lint.py mxnet cpp include src plugin tests \ - --exclude_path src/operator/contrib/ctc_include include/mkldnn - -pylint: - python3 -m pylint --rcfile=$(ROOTDIR)/ci/other/pylintrc --ignore-patterns=".*\.so$$,.*\.dll$$,.*\.dylib$$" python/mxnet - -# MXNet extension dynamically loading libraries -EXT_LIBS = build/libcustomop_lib.so build/libtransposecsr_lib.so build/libtransposerowsp_lib.so build/libsubgraph_lib.so build/libpass_lib.so -ifeq ($(USE_CUDA), 1) - EXT_LIBS += build/libcustomop_gpu_lib.so -endif -extension_libs: $(EXT_LIBS) - -build/libcustomop_lib.so: - @mkdir -p $(@D) - $(CXX) -shared -fPIC -std=c++11 example/extensions/lib_custom_op/gemm_lib.cc -o /dev/null -I include/mxnet - $(CXX) -shared -fPIC -std=c++17 example/extensions/lib_custom_op/gemm_lib.cc -o $@ -I include/mxnet -build/libtransposecsr_lib.so: - @mkdir -p $(@D) - $(CXX) -shared -fPIC -std=c++11 example/extensions/lib_custom_op/transposecsr_lib.cc -o /dev/null -I include/mxnet - $(CXX) -shared -fPIC -std=c++17 example/extensions/lib_custom_op/transposecsr_lib.cc -o $@ -I include/mxnet -build/libtransposerowsp_lib.so: - @mkdir -p $(@D) - $(CXX) -shared -fPIC -std=c++11 example/extensions/lib_custom_op/transposerowsp_lib.cc -o /dev/null -I include/mxnet - $(CXX) -shared -fPIC -std=c++17 example/extensions/lib_custom_op/transposerowsp_lib.cc -o $@ -I include/mxnet -build/libcustomop_gpu_lib.so: - @mkdir -p $(@D) - $(NVCC) -shared -std=c++11 -Xcompiler -fPIC example/extensions/lib_custom_op/relu_lib.cu -o /dev/null -I include/mxnet - $(NVCC) -shared -std=c++14 -Xcompiler -fPIC example/extensions/lib_custom_op/relu_lib.cu -o $@ -I include/mxnet -build/libsubgraph_lib.so: - @mkdir -p $(@D) - $(CXX) -shared -fPIC -std=c++11 example/extensions/lib_subgraph/subgraph_lib.cc -o /dev/null -I include/mxnet - $(CXX) -shared -fPIC -std=c++17 example/extensions/lib_subgraph/subgraph_lib.cc -o $@ -I include/mxnet -build/libpass_lib.so: - @mkdir -p $(@D) - $(CXX) -shared -fPIC -std=c++11 example/extensions/lib_pass/pass_lib.cc -o /dev/null -I include/mxnet - $(CXX) -shared -fPIC -std=c++17 example/extensions/lib_pass/pass_lib.cc -o $@ -I include/mxnet - -# Cython build -cython: - cd python; $(PYTHON) setup.py build_ext --inplace --with-cython - -cython3: - cd python; python3 setup.py build_ext --inplace --with-cython - -cyclean: - rm -rf python/mxnet/*/*.so python/mxnet/*/*.cpp - -build/rat/apache-rat-0.13/apache-rat-0.13.jar: - mkdir -p build/rat - cd build/rat; \ - wget http://mirror.metrocast.net/apache//creadur/apache-rat-0.13/apache-rat-0.13-bin.zip; \ - unzip apache-rat-0.13-bin.zip; - -ratcheck: build/rat/apache-rat-0.13/apache-rat-0.13.jar - exec 5>&1; \ - RAT_JAR=build/rat/apache-rat-0.13/apache-rat-0.13.jar; \ - OUTPUT=$(java -jar $(RAT_JAR) -E tests/nightly/apache_rat_license_check/rat-excludes -d .|tee >(cat - >&5)); \ - ERROR_MESSAGE="Printing headers for text files without a valid license header"; \ - echo "-------Process The Output-------"; \ - if [[ $OUTPUT =~ $ERROR_MESSAGE ]]; then \ - echo "ERROR: RAT Check detected files with unknown licenses. Please fix and run test again!"; \ - exit 1; \ - else \ - echo "SUCCESS: There are no files with an Unknown License."; \ - fi - - -ifneq ($(EXTRA_OPERATORS),) -clean: cyclean $(EXTRA_PACKAGES_CLEAN) - $(RM) -r build lib bin deps *~ */*~ */*/*~ */*/*/*~ - (cd scala-package && mvn clean) || true - cd $(DMLC_CORE); $(MAKE) clean; cd - - cd $(PS_PATH); $(MAKE) clean; cd - - cd $(NNVM_PATH); $(MAKE) clean; cd - - cd $(TVM_PATH); $(MAKE) clean; cd - - $(RM) -r $(patsubst %, %/*.d, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.d, $(EXTRA_OPERATORS)) - $(RM) -r $(patsubst %, %/*.o, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.o, $(EXTRA_OPERATORS)) -else -clean: mkldnn_clean cyclean testclean $(EXTRA_PACKAGES_CLEAN) - $(RM) -r build lib bin *~ */*~ */*/*~ */*/*/*~ - (cd scala-package && mvn clean) || true - cd $(DMLC_CORE); $(MAKE) clean; cd - - cd $(PS_PATH); $(MAKE) clean; cd - - cd $(NNVM_PATH); $(MAKE) clean; cd - - cd $(TVM_PATH); $(MAKE) clean; cd - -endif - -clean_all: clean - --include build/*.d --include build/*/*.d --include build/*/*/*.d --include build/*/*/*/*.d -ifneq ($(EXTRA_OPERATORS),) - -include $(patsubst %, %/*.d, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.d, $(EXTRA_OPERATORS)) -endif diff --git a/README.md b/README.md index 9f1d59e7acd4..60bfe5a57b9c 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ deep learning systems, and interesting insights of DL systems for hackers. Ask Questions ------------- -* Please use [discuss.mxnet.io](https://discuss.mxnet.io/) for asking questions. +* Please use [discuss.d2l.ai](https://discuss.d2l.ai/c/d2l-en/mxnet/) or [old version:discuss.mxnet.io](https://discuss.mxnet.io/) for asking questions. * Please use [mxnet/issues](https://github.com/apache/incubator-mxnet/issues) for reporting bugs. * [Frequent Asked Questions](https://mxnet.apache.org/faq/faq.html) @@ -80,6 +80,7 @@ What's New Contents -------- +* [Book](https://d2l.ai) * [Website](https://mxnet.apache.org) * [Documentation](https://mxnet.apache.org/api) * [Blog](https://mxnet.apache.org/blog) diff --git a/ci/Jenkinsfile_docker_cache b/ci/Jenkinsfile_docker_cache index 96cf2c7bef86..5f378b5d69eb 100644 --- a/ci/Jenkinsfile_docker_cache +++ b/ci/Jenkinsfile_docker_cache @@ -37,7 +37,6 @@ core_logic: { ws('workspace/docker_cache') { timeout(time: total_timeout, unit: 'MINUTES') { utils.init_git() - sh "python3 ./ci/docker_cache.py --docker-registry ${env.DOCKER_CACHE_REGISTRY}" sh "cd ci && python3 ./docker_login.py --secret-name ${env.DOCKERHUB_SECRET_NAME} && docker-compose -f docker/docker-compose.yml pull && docker-compose -f docker/docker-compose.yml build --parallel && COMPOSE_HTTP_TIMEOUT=600 docker-compose -f docker/docker-compose.yml push && docker logout" } } diff --git a/ci/build.py b/ci/build.py index 33f46e5c6b87..f42be1861b19 100755 --- a/ci/build.py +++ b/ci/build.py @@ -18,23 +18,18 @@ # specific language governing permissions and limitations # under the License. -"""Multi arch dockerized build tool. +"""Multi arch dockerized build tool.""" -""" - -__author__ = 'Marco de Abreu, Kellen Sunderland, Anton Chernov, Pedro Larroy' -__version__ = '0.3' +__author__ = 'Marco de Abreu, Kellen Sunderland, Anton Chernov, Pedro Larroy, Leonard Lausen' +__version__ = '0.4' import argparse -import glob import pprint -import re import os -import shutil import signal import subprocess from itertools import chain -from subprocess import check_call, check_output +from subprocess import check_call from typing import * import yaml @@ -42,49 +37,18 @@ from safe_docker_run import SafeDockerClient from util import * -# NOTE: Temporary whitelist used until all Dockerfiles are refactored for docker compose -DOCKER_COMPOSE_WHITELIST = ('centos7_cpu', 'centos7_gpu_cu92', 'centos7_gpu_cu100', - 'centos7_gpu_cu101', 'centos7_gpu_cu102', 'ubuntu_cpu', - 'ubuntu_build_cuda', 'ubuntu_gpu_cu101', 'publish.test.centos7_cpu', - 'publish.test.centos7_gpu', 'android_armv7', 'android_armv8', - 'armv6', 'armv7', 'armv8', 'test.armv7', 'test.armv8') -# Files for docker compose -DOCKER_COMPOSE_FILES = set(('docker/build.centos7', 'docker/build.ubuntu', 'docker/build.android', - 'docker/build.arm', 'docker/test.arm', 'docker/publish.test.centos7')) - - -def get_dockerfiles_path(): - return "docker" - - -def get_platforms(path: str = get_dockerfiles_path(), legacy_only=False) -> List[str]: - """Get a list of architectures given our dockerfiles""" - dockerfiles = glob.glob(os.path.join(path, "Dockerfile.*")) - dockerfiles = set(filter(lambda x: x[-1] != '~', dockerfiles)) - files = set(map(lambda x: re.sub(r"Dockerfile.(.*)", r"\1", x), dockerfiles)) - if legacy_only: - files = files - DOCKER_COMPOSE_FILES - platforms = list(map(lambda x: os.path.split(x)[1], sorted(files))) - return platforms +def get_platforms() -> List[str]: + """Get a list of architectures declared in docker-compose.yml""" + with open("docker/docker-compose.yml", "r") as f: + compose_config = yaml.load(f.read(), yaml.SafeLoader) + return list(compose_config["services"].keys()) def get_docker_tag(platform: str, registry: str) -> str: """:return: docker tag to be used for the container""" - if platform in DOCKER_COMPOSE_WHITELIST: - with open("docker/docker-compose.yml", "r") as f: - compose_config = yaml.load(f.read(), yaml.SafeLoader) - return compose_config["services"][platform]["image"].replace('${DOCKER_CACHE_REGISTRY}', registry) - - platform = platform if any(x in platform for x in ['build.', 'publish.']) else 'build.{}'.format(platform) - if not registry: - registry = "mxnet_local" - return "{0}/{1}".format(registry, platform) - - -def get_dockerfile(platform: str, path=get_dockerfiles_path()) -> str: - platform = platform if any(x in platform for x in ['build.', 'publish.']) else 'build.{}'.format(platform) - return os.path.join(path, "Dockerfile.{0}".format(platform)) - + with open("docker/docker-compose.yml", "r") as f: + compose_config = yaml.load(f.read(), yaml.SafeLoader) + return compose_config["services"][platform]["image"].replace('${DOCKER_CACHE_REGISTRY}', registry) def build_docker(platform: str, registry: str, num_retries: int, no_cache: bool, cache_intermediate: bool = False) -> str: @@ -96,50 +60,18 @@ def build_docker(platform: str, registry: str, num_retries: int, no_cache: bool, :param no_cache: pass no-cache to docker to rebuild the images :return: Id of the top level image """ - tag = get_docker_tag(platform=platform, registry=registry) + logging.info('Building docker container \'%s\' based on ci/docker/docker-compose.yml', platform) + # We add a user with the same group as the executing non-root user so files created in the + # container match permissions of the local user. Same for the group. + cmd = ['docker-compose', '-f', 'docker/docker-compose.yml', 'build', + "--build-arg", "USER_ID={}".format(os.getuid()), + "--build-arg", "GROUP_ID={}".format(os.getgid())] + if cache_intermediate: + cmd.append('--no-rm') + cmd.append(platform) env = os.environ.copy() - - # Case 1: docker-compose - if platform in DOCKER_COMPOSE_WHITELIST: - logging.info('Building docker container tagged \'%s\' based on ci/docker/docker-compose.yml', tag) - # We add a user with the same group as the executing non-root user so files created in the - # container match permissions of the local user. Same for the group. - cmd = ['docker-compose', '-f', 'docker/docker-compose.yml', 'build', - "--build-arg", "USER_ID={}".format(os.getuid()), - "--build-arg", "GROUP_ID={}".format(os.getgid())] - if cache_intermediate: - cmd.append('--no-rm') - cmd.append(platform) - env["DOCKER_CACHE_REGISTRY"] = registry - else: # Case 2: Deprecated way, will be removed - # We add a user with the same group as the executing non-root user so files created in the - # container match permissions of the local user. Same for the group. - # - # These variables are used in the docker files to create user and group with these ids. - # see: docker/install/ubuntu_adduser.sh - # - # cache-from is needed so we use the cached images tagged from the remote via - # docker pull see: docker_cache.load_docker_cache - # - # This also prevents using local layers for caching: https://github.com/moby/moby/issues/33002 - # So to use local caching, we should omit the cache-from by using --no-dockerhub-cache argument to this - # script. - # - # This doesn't work with multi head docker files. - logging.info("Building docker container tagged '%s'", tag) - cmd = ["docker", "build", - "-f", get_dockerfile(platform), - "--build-arg", "USER_ID={}".format(os.getuid()), - "--build-arg", "GROUP_ID={}".format(os.getgid())] - if no_cache: - cmd.append("--no-cache") - if cache_intermediate: - cmd.append("--rm=false") - elif registry: - cmd.extend(["--cache-from", tag]) - cmd.extend(["-t", tag, get_dockerfiles_path()]) - + env["DOCKER_CACHE_REGISTRY"] = registry @retry(subprocess.CalledProcessError, tries=num_retries) def run_cmd(env=None): @@ -148,27 +80,6 @@ def run_cmd(env=None): run_cmd(env=env) - # Get image id by reading the tag. It's guaranteed (except race condition) that the tag exists. Otherwise, the - # check_call would have failed - image_id = _get_local_image_id(docker_tag=tag) - if not image_id: - raise FileNotFoundError('Unable to find docker image id matching with {}'.format(tag)) - return image_id - - -def _get_local_image_id(docker_tag): - """ - Get the image id of the local docker layer with the passed tag - :param docker_tag: docker tag - :return: Image id as string or None if tag does not exist - """ - cmd = ["docker", "images", "-q", docker_tag] - image_id_b = check_output(cmd) - image_id = image_id_b.decode('utf-8').strip() - if not image_id: - raise RuntimeError('Unable to find docker image id matching with tag {}'.format(docker_tag)) - return image_id - def buildir() -> str: return os.path.join(get_mxnet_root(), "build") @@ -288,16 +199,14 @@ def list_platforms() -> str: return "\nSupported platforms:\n{}".format('\n'.join(get_platforms())) -def load_docker_cache(tag, docker_registry) -> None: +def load_docker_cache(platform, tag, docker_registry) -> None: """Imports tagged container from the given docker registry""" if docker_registry: - # noinspection PyBroadException - try: - import docker_cache - logging.info('Docker cache download is enabled from registry %s', docker_registry) - docker_cache.load_docker_cache(registry=docker_registry, docker_tag=tag) - except Exception: - logging.exception('Unable to retrieve Docker cache. Continue without...') + env = os.environ.copy() + env["DOCKER_CACHE_REGISTRY"] = docker_registry + cmd = ['docker-compose', '-f', 'docker/docker-compose.yml', 'pull', platform] + logging.info("Running command: 'DOCKER_CACHE_REGISTRY=%s %s'", docker_registry, ' '.join(cmd)) + check_call(cmd, env=env) else: logging.info('Distributed docker cache disabled') @@ -319,9 +228,9 @@ def main() -> int: parser = argparse.ArgumentParser(description="""Utility for building and testing MXNet on docker containers""", epilog="") - parser.add_argument("-p", "--platform", - help="platform", - type=str) + parser.add_argument("-p", "--platform", type=str, help= \ + "Platform. See ci/docker/docker-compose.yml for list of supported " \ + "platforms (services).") parser.add_argument("-b", "--build-only", help="Only build the container, don't build the project", @@ -331,10 +240,6 @@ def main() -> int: help="Only run the container, don't rebuild the container", action='store_true') - parser.add_argument("-a", "--all", - help="build for all platforms", - action='store_true') - parser.add_argument("-n", "--nvidiadocker", help="Use nvidia docker", action='store_true') @@ -398,7 +303,7 @@ def main() -> int: platform = args.platform tag = get_docker_tag(platform=platform, registry=args.docker_registry) if args.docker_registry and not args.no_pull: - load_docker_cache(tag=tag, docker_registry=args.docker_registry) + load_docker_cache(platform=platform, tag=tag, docker_registry=args.docker_registry) if not args.run_only: build_docker(platform=platform, registry=args.docker_registry, num_retries=args.docker_build_retries, no_cache=args.no_cache, cache_intermediate=args.cache_intermediate) @@ -435,32 +340,6 @@ def main() -> int: logging.critical("Execution of %s failed with status: %d", command, ret) return ret - elif args.all: - platforms = get_platforms() - platforms = [platform for platform in platforms if 'build.' in platform] - logging.info("Building for all architectures: %s", platforms) - logging.info("Artifacts will be produced in the build/ directory.") - for platform in platforms: - tag = get_docker_tag(platform=platform, registry=args.docker_registry) - load_docker_cache(tag=tag, docker_registry=args.docker_registry) - build_docker(platform, registry=args.docker_registry, num_retries=args.docker_build_retries, - no_cache=args.no_cache) - if args.build_only: - continue - shutil.rmtree(buildir(), ignore_errors=True) - build_platform = "build_{}".format(platform) - plat_buildir = os.path.abspath(os.path.join(get_mxnet_root(), '..', - "mxnet_{}".format(build_platform))) - if os.path.exists(plat_buildir): - logging.warning("%s already exists, skipping", plat_buildir) - continue - command = ["/work/mxnet/ci/docker/runtime_functions.sh", build_platform] - container_run( - docker_client=docker_client, platform=platform, nvidia_runtime=args.nvidiadocker, - shared_memory_size=args.shared_memory_size, command=command, docker_registry=args.docker_registry, - local_ccache_dir=args.ccache_dir, environment=environment) - shutil.move(buildir(), plat_buildir) - logging.info("Built files left in: %s", plat_buildir) else: parser.print_help() diff --git a/ci/dev_menu.py b/ci/dev_menu.py index c471302c76d7..dcc01723d83d 100644 --- a/ci/dev_menu.py +++ b/ci/dev_menu.py @@ -122,7 +122,7 @@ def provision_virtualenv(venv_path=DEFAULT_PYENV): "pytest -v tests/python/unittest/" ), ('[Docker] Build the MXNet binary - outputs to "lib/"', - "ci/build.py --platform ubuntu_cpu_lite /work/runtime_functions.sh build_ubuntu_cpu_docs"), + "ci/build.py --platform ubuntu_cpu /work/runtime_functions.sh build_ubuntu_cpu_docs"), ('[Docker] Build the Jekyll website - outputs to "docs/static_site/build/html/"', "ci/build.py --platform ubuntu_cpu_jekyll /work/runtime_functions.sh build_jekyll_docs"), ('[Docker] Build the Python API docs - outputs to "docs/python_docs/python/build/_build/html/"', @@ -130,7 +130,6 @@ def provision_virtualenv(venv_path=DEFAULT_PYENV): ('[Docker] sanity_check. Check for linting and code formatting and licenses.', [ "ci/build.py --platform ubuntu_cpu /work/runtime_functions.sh sanity_check", - "ci/build.py --platform ubuntu_rat /work/runtime_functions.sh nightly_test_rat_check", ]), ('[Docker] Python3 CPU unittests', [ diff --git a/ci/docker/Dockerfile.build.centos7 b/ci/docker/Dockerfile.build.centos7 index a0b5b127e7ea..8a718c4d1339 100644 --- a/ci/docker/Dockerfile.build.centos7 +++ b/ci/docker/Dockerfile.build.centos7 @@ -119,22 +119,14 @@ RUN export SHORT_CUDA_VERSION=${CUDA_VERSION%.*} && \ yum clean all; \ fi -# Python dependencies -RUN pip3 install --no-cache-dir --upgrade pip && \ - pip3 install --no-cache-dir pylint cython numpy requests h5py scipy==1.2.3 wheel \ - pytest==5.3.5 \ - pytest-env==0.6.2 \ - pytest-cov==2.8.1 \ - pytest-xdist==1.31.0 \ - pytest-timeout==1.3.4 \ - mock==2.0.0 \ - onnx==1.5.0 \ - protobuf==3.5.2 \ - tabulate==0.7.5 - # Fix the en_DK.UTF-8 locale to test locale invariance RUN localedef -i en_DK -f UTF-8 en_DK.UTF-8 +# Python dependencies +RUN python3 -m pip install --upgrade pip +COPY install/requirements /work/ +RUN python3 -m pip install -r /work/requirements + ARG USER_ID=0 COPY install/docker_filepermissions.sh /work/ RUN /work/docker_filepermissions.sh diff --git a/ci/docker/Dockerfile.build.jetson b/ci/docker/Dockerfile.build.jetson index 93fe5e0a5b0d..93c5558d2228 100644 --- a/ci/docker/Dockerfile.build.jetson +++ b/ci/docker/Dockerfile.build.jetson @@ -20,7 +20,7 @@ # This script assumes /work/mxnet exists and contains the mxnet code you wish to compile and # that /work/build exists and is the target for your output. -FROM nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04 +FROM nvidia/cuda:10.2-cudnn7-devel-ubuntu18.04 ENV ARCH=aarch64 \ HOSTCC=gcc \ @@ -32,7 +32,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ build-essential \ ninja-build \ git \ - curl \ + wget \ zip \ unzip \ python3 \ @@ -58,21 +58,38 @@ RUN git clone --recursive -b v0.3.9 https://github.com/xianyi/OpenBLAS.git && \ cd /usr/local && \ rm -rf OpenBLAS -# Install aarch64 cross depedencies based on Jetpack 4.3 -# Manually downloaded using SDK Manager tool and placed in a private S3 bucket. -# We're not allowed to redistribute these files and there is no public version. -RUN aws s3 cp s3://mxnet-ci-prod-private-slave-data/nvidia/sdkm_downloads/cuda-repo-ubuntu1804-10-0-local-10.0.326-410.108_1.0-1_amd64.deb . && \ - dpkg -i cuda-repo-ubuntu1804-10-0-local-10.0.326-410.108_1.0-1_amd64.deb && \ - rm cuda-repo-ubuntu1804-10-0-local-10.0.326-410.108_1.0-1_amd64.deb && \ - apt-key add /var/cuda-repo-10-0-local-10.0.326-410.108/7fa2af80.pub && \ - aws s3 cp s3://mxnet-ci-prod-private-slave-data/nvidia/sdkm_downloads/cuda-repo-cross-aarch64-10-0-local-10.0.326_1.0-1_all.deb . && \ - dpkg -i cuda-repo-cross-aarch64-10-0-local-10.0.326_1.0-1_all.deb && \ - rm cuda-repo-cross-aarch64-10-0-local-10.0.326_1.0-1_all.deb && \ +# Install aarch64 cross depedencies based on Jetpack 4.4 +# Dependencies require cuda-toolkit-10.2 which isn't installed in nvidia docker container +# It contains cuda-compat instead. However deb files currently depend on cuda-toolkit alone. +# Hence force dpkg configure +RUN wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cross-aarch64_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cudart-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cufft-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cupti-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-curand-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cusolver-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-cusparse-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-driver-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-misc-headers-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-npp-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-nsight-compute-addon-l4t-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-nvgraph-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-nvml-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cuda/cuda-nvrtc-cross-aarch64-10-2_10.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/c/cublas/libcublas-cross-aarch64_10.2.2.89-1_all.deb && \ + wget https://repo.download.nvidia.com/jetson/x86_64/pool/r32.4/n/nsight-compute/nsight-compute-addon-l4t-2019.5.0_2019.5.0.14-1_all.deb && \ + dpkg -i --force-all *.deb && \ + rm *.deb && \ apt-get update && \ apt-get install -y -f && \ - apt-get install -y cuda-cross-aarch64 cuda-cross-aarch64-10-0 && \ + apt-get install -y cuda-cross-aarch64 cuda-cross-aarch64-10-2 && \ rm -rf /var/lib/apt/lists/* +# nvidia jetpack 4.4 installs libcublas.so at /usr/lib/aarch64-linux-gnu +# while previously it used to store it at /usr/local/cuda/targets/aarch64-linux/lib/stubs +RUN ln -s /usr/lib/aarch64-linux-gnu/libcublas.so /usr/local/cuda/targets/aarch64-linux/lib/stubs/libcublas.so + ARG USER_ID=0 ARG GROUP_ID=0 COPY install/ubuntu_adduser.sh /work/ diff --git a/ci/docker/Dockerfile.build.ubuntu b/ci/docker/Dockerfile.build.ubuntu index 415e6ae881ae..8398dc9bee54 100644 --- a/ci/docker/Dockerfile.build.ubuntu +++ b/ci/docker/Dockerfile.build.ubuntu @@ -53,9 +53,9 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ protobuf-compiler \ libprotobuf-dev \ clang-6.0 \ - clang-tidy-6.0 \ python-yaml \ clang-10 \ + clang-tidy-10 \ g++ \ g++-8 \ intel-mkl-2020.0-088 \ @@ -68,9 +68,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libzmq3-dev \ liblapack-dev \ libopencv-dev \ - # Caffe - caffe-cpu \ - libcaffe-cpu-dev \ + libxml2-dev \ # BytePS numactl \ libnuma-dev \ @@ -80,23 +78,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ python3-pip \ python3-nose \ python3-nose-timer \ - # Scala - openjdk-8-jdk \ - openjdk-8-jre \ - maven \ - scala \ - # Clojure - clojure \ - leiningen \ - # R - r-base-core \ - r-cran-devtools \ - libcairo2-dev \ - libxml2-dev \ ## Documentation doxygen \ pandoc \ ## Build-dependencies for ccache 3.7.9 + autoconf \ gperf \ libb2-dev \ libzstd-dev && \ @@ -114,22 +100,16 @@ RUN cd /usr/local/src && \ cd /usr/local/src && \ rm -rf ccache +# RAT License Checker tool +RUN cd /usr/local/src && \ + wget https://archive.apache.org/dist/creadur/apache-rat-0.13/apache-rat-0.13-bin.tar.gz && \ + tar xf apache-rat-0.13-bin.tar.gz + # Python & cmake COPY install/requirements /work/ RUN python3 -m pip install cmake==3.16.6 && \ python3 -m pip install -r /work/requirements -# Only OpenJDK 8 supported at this time.. -RUN update-java-alternatives -s java-1.8.0-openjdk-amd64 - -# julia not available on 18.04 -COPY install/ubuntu_julia.sh /work/ -RUN /work/ubuntu_julia.sh - -# MXNetJS nightly needs emscripten for wasm -COPY install/ubuntu_emscripten.sh /work/ -RUN /work/ubuntu_emscripten.sh - ARG USER_ID=0 COPY install/docker_filepermissions.sh /work/ RUN /work/docker_filepermissions.sh @@ -152,6 +132,23 @@ RUN cd /usr/local && \ cd thrust && \ git checkout 1.9.8 +# Install TensorRT +# We need to redeclare ARG due to +# https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG BASE_IMAGE +RUN export SHORT_CUDA_VERSION=${CUDA_VERSION%.*} && \ + apt-get update && \ + if [ ${SHORT_CUDA_VERSION} = 10.0 ]; then \ + apt-get install -y "libnvinfer-dev=5.1.5-1+cuda10.0"; \ + elif [ ${SHORT_CUDA_VERSION} = 10.1 ]; then \ + apt-get install -y "libnvinfer-dev=5.1.5-1+cuda10.1"; \ + elif [ ${SHORT_CUDA_VERSION} = 10.2 ]; then \ + apt-get install -y "libnvinfer-dev=6.0.1-1+cuda10.2"; \ + else \ + echo "ERROR: Cuda ${SHORT_CUDA_VERSION} not yet supported in Dockerfile.build.ubuntu"; \ + exit 1; \ + fi && \ + rm -rf /var/lib/apt/lists/* FROM gpu as gpuwithcudaruntimelibs # Special case because the CPP-Package requires the CUDA runtime libs diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_c b/ci/docker/Dockerfile.build.ubuntu_cpu_c deleted file mode 100644 index c7969da1bb1d..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_c +++ /dev/null @@ -1,35 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh - -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh - -RUN apt-get update && apt-get install -y doxygen graphviz - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet \ No newline at end of file diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_jekyll b/ci/docker/Dockerfile.build.ubuntu_cpu_jekyll index 52ed2e083c69..6586a4e907d3 100644 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_jekyll +++ b/ci/docker/Dockerfile.build.ubuntu_cpu_jekyll @@ -18,53 +18,28 @@ # # Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU -FROM ubuntu:16.04 +FROM ruby:2.6.5-buster WORKDIR /work/deps -SHELL ["/bin/bash", "-l", "-c" ] - -RUN apt-get update && apt-get install -y \ - build-essential \ - git \ - zlib1g-dev \ - gnupg2 \ - curl \ - wget \ - unzip - -# Always last, except here to prevent conflicts with rvm -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -RUN curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - && \ - curl -sSL https://rvm.io/pkuczynski.asc | gpg2 --import - && \ - curl -sSL https://get.rvm.io | bash -s stable - -RUN source /etc/profile.d/rvm.sh && \ - rvm requirements && \ - rvm install 2.6.5 && \ - rvm use 2.6.5 --default - ENV BUNDLE_HOME=/work/deps/bundle ENV BUNDLE_APP_CONFIG=/work/deps/bundle ENV BUNDLE_BIN=/work/deps/bundle/bin ENV GEM_BIN=/work/deps/gem/bin ENV GEM_HOME=/work/deps/gem -RUN echo "gem: --no-ri --no-rdoc" > ~/.gemrc -RUN yes | gem update --system -RUN yes | gem install --force bundler -RUN gem install jekyll +RUN echo "gem: --no-ri --no-rdoc" > ~/.gemrc && \ + yes | gem update --system && \ + yes | gem install --force bundler && \ + gem install jekyll ENV PATH=$BUNDLE_BIN:$GEM_BIN:$PATH COPY runtime_functions.sh /work/ -RUN chown -R jenkins_slave /work/ && \ - chown -R jenkins_slave /usr/local/bin && \ - chown -R jenkins_slave /usr/local/rvm +ARG USER_ID=0 +ARG GROUP_ID=0 +COPY install/ubuntu_adduser.sh /work/ +RUN /work/ubuntu_adduser.sh WORKDIR /work/mxnet diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_julia b/ci/docker/Dockerfile.build.ubuntu_cpu_julia deleted file mode 100644 index e100d4df09a8..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_julia +++ /dev/null @@ -1,66 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh - -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh - -COPY install/ubuntu_python.sh /work/ -COPY install/requirements /work/ -RUN /work/ubuntu_python.sh - -COPY install/ubuntu_scala.sh /work/ -COPY install/sbt.gpg /work/ -RUN /work/ubuntu_scala.sh - -COPY install/ubuntu_clojure.sh /work/ -RUN /work/ubuntu_clojure.sh - -COPY install/ubuntu_julia.sh /work/ -RUN /work/ubuntu_julia.sh - -COPY install/ubuntu_clang.sh /work/ -RUN /work/ubuntu_clang.sh - -COPY install/ubuntu_gcc8.sh /work/ -RUN /work/ubuntu_gcc8.sh - -COPY install/ubuntu_r.sh /work/ -COPY install/r.gpg /work/ -RUN /work/ubuntu_r.sh - -COPY install/ubuntu_docs.sh /work/ -RUN /work/ubuntu_docs.sh - -# Always last -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_lite b/ci/docker/Dockerfile.build.ubuntu_cpu_lite deleted file mode 100644 index ca5618ac1cd7..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_lite +++ /dev/null @@ -1,45 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh - -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh - -COPY install/ubuntu_clang.sh /work/ -RUN /work/ubuntu_clang.sh - -COPY install/ubuntu_gcc8.sh /work/ -RUN /work/ubuntu_gcc8.sh - -# Always last -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet \ No newline at end of file diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_r b/ci/docker/Dockerfile.build.ubuntu_cpu_r deleted file mode 100644 index 2354cb3b66d6..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_r +++ /dev/null @@ -1,46 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh - -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh - -COPY install/ubuntu_gcc8.sh /work/ -RUN /work/ubuntu_gcc8.sh - -COPY install/ubuntu_r.sh /work/ -COPY install/r.gpg /work/ -RUN /work/ubuntu_r.sh - -# Always last -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet diff --git a/ci/docker/Dockerfile.build.ubuntu_cpu_scala b/ci/docker/Dockerfile.build.ubuntu_cpu_scala deleted file mode 100644 index a36e4426c39c..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_cpu_scala +++ /dev/null @@ -1,53 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh - -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh - -COPY install/ubuntu_gcc8.sh /work/ -RUN /work/ubuntu_gcc8.sh - -COPY install/ubuntu_python.sh /work/ -COPY install/requirements /work/ -RUN /work/ubuntu_python.sh - -COPY install/ubuntu_scala.sh /work/ -COPY install/sbt.gpg /work/ -RUN /work/ubuntu_scala.sh - -COPY install/ubuntu_clojure.sh /work/ -RUN /work/ubuntu_clojure.sh - -# Always last -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet diff --git a/ci/docker/Dockerfile.build.ubuntu_gpu_tensorrt b/ci/docker/Dockerfile.build.ubuntu_gpu_tensorrt deleted file mode 100644 index 90bd772ecb17..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_gpu_tensorrt +++ /dev/null @@ -1,47 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to run MXNet on Ubuntu 16.04 for CPU - -FROM nvidia/cuda:10.0-devel - -WORKDIR /work/deps - -COPY install/ubuntu_core.sh /work/ -RUN /work/ubuntu_core.sh -COPY install/deb_ubuntu_ccache.sh /work/ -RUN /work/deb_ubuntu_ccache.sh -COPY install/ubuntu_python.sh /work/ -COPY install/requirements /work/ -RUN /work/ubuntu_python.sh -COPY install/tensorrt.sh /work -RUN /work/tensorrt.sh - -ARG USER_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -ENV CUDNN_VERSION=7.5.0.56 -COPY install/ubuntu_cudnn.sh /work/ -RUN /work/ubuntu_cudnn.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib -ENV CPLUS_INCLUDE_PATH=${CPLUS_INCLUDE_PATH}:/usr/local/cuda-10.0/targets/x86_64-linux/include/ diff --git a/ci/docker/Dockerfile.build.ubuntu_rat b/ci/docker/Dockerfile.build.ubuntu_rat deleted file mode 100644 index 234d2e42e946..000000000000 --- a/ci/docker/Dockerfile.build.ubuntu_rat +++ /dev/null @@ -1,36 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to run the Apache RAT license check - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_rat.sh /work/ -RUN /work/ubuntu_rat.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.test.ubuntu1604_cpu b/ci/docker/Dockerfile.publish.test.ubuntu1604_cpu deleted file mode 100644 index bbb7b6a0d7bd..000000000000 --- a/ci/docker/Dockerfile.publish.test.ubuntu1604_cpu +++ /dev/null @@ -1,39 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_scala.sh /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.test.ubuntu1604_gpu b/ci/docker/Dockerfile.publish.test.ubuntu1604_gpu deleted file mode 100644 index 660461dc0cfa..000000000000 --- a/ci/docker/Dockerfile.publish.test.ubuntu1604_gpu +++ /dev/null @@ -1,39 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to run MXNet on Ubuntu 16.04 for GPU - -FROM nvidia/cuda:9.2-cudnn7-devel-ubuntu16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_scala.sh /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.test.ubuntu1804_cpu b/ci/docker/Dockerfile.publish.test.ubuntu1804_cpu deleted file mode 100644 index e3a8c193f234..000000000000 --- a/ci/docker/Dockerfile.publish.test.ubuntu1804_cpu +++ /dev/null @@ -1,41 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 18.04 for CPU - -FROM ubuntu:18.04 - -WORKDIR /work/deps - -ENV DEBIAN_FRONTEND noninteractive - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_scala.sh /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.test.ubuntu1804_gpu b/ci/docker/Dockerfile.publish.test.ubuntu1804_gpu deleted file mode 100644 index 99f7e0d3eff9..000000000000 --- a/ci/docker/Dockerfile.publish.test.ubuntu1804_gpu +++ /dev/null @@ -1,41 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to run MXNet on Ubuntu 18.04 for GPU - -FROM nvidia/cuda:9.2-cudnn7-devel-ubuntu18.04 - -WORKDIR /work/deps - -ENV DEBIAN_FRONTEND noninteractive - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_scala.sh /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.ubuntu1604_cpu b/ci/docker/Dockerfile.publish.ubuntu1604_cpu deleted file mode 100644 index e5898b66c161..000000000000 --- a/ci/docker/Dockerfile.publish.ubuntu1604_cpu +++ /dev/null @@ -1,44 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to build and run MXNet on Ubuntu 16.04 for CPU - -FROM ubuntu:16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_python.sh /work/ -COPY install/requirements /work/ -RUN /work/ubuntu_python.sh - -COPY install/ubuntu_scala.sh /work/ -COPY install/sbt.gpg /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/Dockerfile.publish.ubuntu1604_gpu b/ci/docker/Dockerfile.publish.ubuntu1604_gpu deleted file mode 100644 index 0bd8b8259b90..000000000000 --- a/ci/docker/Dockerfile.publish.ubuntu1604_gpu +++ /dev/null @@ -1,44 +0,0 @@ -# -*- mode: dockerfile -*- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -# -# Dockerfile to run MXNet on Ubuntu 16.04 for GPU - -FROM nvidia/cuda:9.2-cudnn7-devel-ubuntu16.04 - -WORKDIR /work/deps - -COPY install/ubuntu_base.sh /work/ -RUN /work/ubuntu_base.sh - -COPY install/ubuntu_python.sh /work/ -COPY install/requirements /work/ -RUN /work/ubuntu_python.sh - -COPY install/ubuntu_scala.sh /work/ -COPY install/sbt.gpg /work/ -RUN /work/ubuntu_scala.sh - -ARG USER_ID=0 -ARG GROUP_ID=0 -COPY install/ubuntu_adduser.sh /work/ -RUN /work/ubuntu_adduser.sh - -COPY runtime_functions.sh /work/ - -WORKDIR /work/mxnet -ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib diff --git a/ci/docker/docker-compose.yml b/ci/docker/docker-compose.yml index 73beb232b1ca..cced098d7f11 100644 --- a/ci/docker/docker-compose.yml +++ b/ci/docker/docker-compose.yml @@ -206,3 +206,34 @@ services: BASE_IMAGE: nvidia/cuda:9.2-cudnn7-devel-centos7 cache_from: - ${DOCKER_CACHE_REGISTRY}/publish.test.centos7_gpu:latest + ################################################################################################### + # Miscellaneous containers + ################################################################################################### + jetson: + image: ${DOCKER_CACHE_REGISTRY}/build.jetson:latest + build: + context: . + dockerfile: Dockerfile.build.jetson + cache_from: + - ${DOCKER_CACHE_REGISTRY}/build.jetson:latest + ubuntu_cpu_jekyll: + image: ${DOCKER_CACHE_REGISTRY}/build.ubuntu_cpu_jekyll:latest + build: + context: . + dockerfile: Dockerfile.build.ubuntu_cpu_jekyll + cache_from: + - ${DOCKER_CACHE_REGISTRY}/build.ubuntu_cpu_jekyll:latest + ubuntu_cpu_python: + image: ${DOCKER_CACHE_REGISTRY}/build.ubuntu_cpu_python:latest + build: + context: . + dockerfile: Dockerfile.build.ubuntu_cpu_python + cache_from: + - ${DOCKER_CACHE_REGISTRY}/build.ubuntu_cpu_python:latest + ubuntu_blc: + image: ${DOCKER_CACHE_REGISTRY}/build.ubuntu_blc:latest + build: + context: . + dockerfile: Dockerfile.build.ubuntu_blc + cache_from: + - ${DOCKER_CACHE_REGISTRY}/build.ubuntu_blc:latest diff --git a/ci/docker/install/export_gpg_keys.sh b/ci/docker/install/export_gpg_keys.sh deleted file mode 100755 index 604a27b98143..000000000000 --- a/ci/docker/install/export_gpg_keys.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -gpg --keyserver keyserver.ubuntu.com --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823 -gpg --output sbt.gpg --export scalasbt@gmail.com -gpg --keyserver keyserver.ubuntu.com --recv E084DAB9 -gpg --output r.gpg --export marutter@gmail.com diff --git a/ci/docker/install/r.gpg b/ci/docker/install/r.gpg deleted file mode 100644 index 77fd6341e9d4..000000000000 Binary files a/ci/docker/install/r.gpg and /dev/null differ diff --git a/ci/docker/install/requirements b/ci/docker/install/requirements index ce06681d96af..bd0114ce0464 100644 --- a/ci/docker/install/requirements +++ b/ci/docker/install/requirements @@ -22,6 +22,7 @@ numpy>=1.17 requests>=2.20.0,<3 graphviz<0.9.0,>=0.8.1 +contextvars;python_version<"3.7" # Optional dependencies onnx==1.5.0 @@ -42,6 +43,7 @@ pytest-xdist==1.31.0 pytest-timeout==1.3.4 flaky==3.6.1 setuptools +wheel mock==2.0.0 # TVM dependencies diff --git a/ci/docker/install/sbt.gpg b/ci/docker/install/sbt.gpg deleted file mode 100644 index 664f01b37d01..000000000000 Binary files a/ci/docker/install/sbt.gpg and /dev/null differ diff --git a/ci/docker/install/tensorrt.sh b/ci/docker/install/tensorrt.sh deleted file mode 100755 index e98c7643f923..000000000000 --- a/ci/docker/install/tensorrt.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# Install gluoncv since we're testing Gluon models as well -pip3 install gluoncv==0.2.0 - -# Install Protobuf -# Install protoc 3.5 and build protobuf here (for onnx and onnx-tensorrt) -pushd . -cd .. -apt-get update -apt-get install -y automake libtool zip -git clone --recursive -b 3.5.1.1 https://github.com/google/protobuf.git -cd protobuf -./autogen.sh -./configure --disable-shared CXXFLAGS=-fPIC -make -j$(nproc) -make install -rm -rf /usr/local/lib/libprotobuf-lite.so* -rm -rf /usr/local/lib/libprotobuf.so* -rm -rf /usr/local/lib/libprotoc.so* -ldconfig -popd - -# Install TensorRT -echo "TensorRT build enabled. Installing TensorRT." -wget -qO tensorrt.deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb -dpkg -i tensorrt.deb -apt-get update -apt-get install -y --allow-downgrades libnvinfer5=5.1.5-1+cuda10.0 -apt-get install -y --allow-downgrades libnvinfer-dev=5.1.5-1+cuda10.0 -apt-mark hold libnvinfer5 libnvinfer-dev -rm tensorrt.deb diff --git a/ci/docker/install/ubuntu_base.sh b/ci/docker/install/ubuntu_base.sh deleted file mode 100755 index f36e53279f57..000000000000 --- a/ci/docker/install/ubuntu_base.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -set -ex -apt-get update || true -apt-get install -y \ - build-essential \ - ca-certificates \ - cmake \ - curl \ - git \ - ninja-build \ - libgfortran3 \ - software-properties-common \ - sudo \ - unzip \ - expect \ - gnupg \ - gnupg2 \ - gnupg-agent \ - wget diff --git a/ci/docker/install/ubuntu_clang.sh b/ci/docker/install/ubuntu_clang.sh deleted file mode 100755 index c81f10dfb664..000000000000 --- a/ci/docker/install/ubuntu_clang.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -set -ex - -# Install clang 3.9 (the same version as in XCode 8.*) and 10 (latest major release) -wget -qO - http://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ - apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main" && \ - apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main" && \ - apt-add-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" && \ - apt-get update && \ - apt-get install -y clang-3.9 clang-6.0 clang-10 clang-tidy-6.0 && \ - clang-3.9 --version && \ - clang-6.0 --version && \ - clang-10 --version - -# TODO(leezu) switch to clang-tidy 10 -# Use llvm's master version of run-clang-tidy.py. This version has mostly minor updates, but -# importantly will properly return a non-zero exit code when an error is reported in clang-tidy. -# Please remove the below if we install a clang version higher than 6.0. -wget \ - -qO /usr/lib/llvm-6.0/share/clang/run-clang-tidy.py\ - https://raw.githubusercontent.com/llvm-mirror/clang-tools-extra/7654135f0cbd155c285fd2a37d87e27e4fff3071/clang-tidy/tool/run-clang-tidy.py diff --git a/ci/docker/install/ubuntu_clojure.sh b/ci/docker/install/ubuntu_clojure.sh deleted file mode 100755 index dcaae6ba048d..000000000000 --- a/ci/docker/install/ubuntu_clojure.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -set -ex -# install libraries for mxnet's clojure package on ubuntu -echo 'Installing Clojure...' - -wget -q https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein -chmod 775 lein -sudo cp lein /usr/local/bin -echo "Y" | sudo lein downgrade 2.8.3 diff --git a/ci/docker/install/ubuntu_cudnn.sh b/ci/docker/install/ubuntu_cudnn.sh deleted file mode 100755 index eaf50447305c..000000000000 --- a/ci/docker/install/ubuntu_cudnn.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -# Assumes base image is from nvidia/cuda - -set -ex - -if [ -z ${CUDNN_VERSION} ]; then - echo "Error: CUDNN_VERSION environment variable undefiend" - exit 1 -fi - -apt-get update || true - -case ${CUDA_VERSION} in - 10\.2*) - export libcudnn7_version="${CUDNN_VERSION}-1+cuda10.2" - export libcudnn7_dev_version="${CUDNN_VERSION}-1+cuda10.2" - ;; - 10\.1*) - export libcudnn7_version="${CUDNN_VERSION}-1+cuda10.1" - export libcudnn7_dev_version="${CUDNN_VERSION}-1+cuda10.1" - ;; - 10\.0*) - export libcudnn7_version="${CUDNN_VERSION}-1+cuda10.0" - export libcudnn7_dev_version="${CUDNN_VERSION}-1+cuda10.0" - ;; - 9\.0*) - export libcudnn7_version="${CUDNN_VERSION}-1+cuda9.0" - export libcudnn7_dev_version="${CUDNN_VERSION}-1+cuda9.0" - ;; - 9\.2*) - export libcudnn7_version="${CUDNN_VERSION}-1+cuda9.2" - export libcudnn7_dev_version="${CUDNN_VERSION}-1+cuda9.2" - ;; - *) - echo "Unsupported CUDA version ${CUDA_VERSION}" - exit 1 - ;; -esac - -apt-get install -y --allow-downgrades libcudnn7=${libcudnn7_version} libcudnn7-dev=${libcudnn7_dev_version} - diff --git a/ci/docker/install/ubuntu_emscripten.sh b/ci/docker/install/ubuntu_emscripten.sh deleted file mode 100755 index 28ede755f5c7..000000000000 --- a/ci/docker/install/ubuntu_emscripten.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -#The script has been copied as is from a dockerfile that existed on previous MXNet versions (0.11) -#Written By: Ly - -set -ex - -apt-get update || true -apt-get -y install nodejs - -git clone -b 1.38.6 https://github.com/kripken/emscripten.git -git clone -b 1.38.6 https://github.com/kripken/emscripten-fastcomp -cd emscripten-fastcomp -git clone -b 1.38.6 https://github.com/kripken/emscripten-fastcomp-clang tools/clang -mkdir build && cd build - -cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86;JSBackend" \ --DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DCLANG_INCLUDE_EXAMPLES=OFF \ --DCLANG_INCLUDE_TESTS=OFF && make -j$(nproc) - -chmod -R 777 /work/deps/emscripten-fastcomp/ diff --git a/ci/docker/install/ubuntu_gcc8.sh b/ci/docker/install/ubuntu_gcc8.sh deleted file mode 100755 index e0f2986e101f..000000000000 --- a/ci/docker/install/ubuntu_gcc8.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -sudo add-apt-repository ppa:jonathonf/gcc-8.0 -sudo add-apt-repository ppa:jonathonf/gcc-7.3 -sudo apt-get update || true -sudo apt-get install -y gcc-8 g++-8 gcc-7 g++-7 diff --git a/ci/docker/install/ubuntu_julia.sh b/ci/docker/install/ubuntu_julia.sh deleted file mode 100755 index 435ec46db6c7..000000000000 --- a/ci/docker/install/ubuntu_julia.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -set -ex - -function install_julia() { - local suffix=`echo $1 | sed 's/\.//'` # 0.7 -> 07; 1.0 -> 10 - local JLBINARY="julia-$1.tar.gz" - local JULIADIR="/work/julia$suffix" - local JULIA="${JULIADIR}/bin/julia" - - mkdir -p $JULIADIR - # The julia version in Ubuntu repo is too old - # We download the tarball from the official link: - # https://julialang.org/downloads/ - wget -qO $JLBINARY https://julialang-s3.julialang.org/bin/linux/x64/$1/julia-$2-linux-x86_64.tar.gz - tar xzf $JLBINARY -C $JULIADIR --strip 1 - rm $JLBINARY - - $JULIA -e 'using InteractiveUtils; versioninfo()' -} - -install_julia 0.7 0.7.0 -install_julia 1.0 1.0.4 diff --git a/ci/docker/install/ubuntu_nightly_tests.sh b/ci/docker/install/ubuntu_nightly_tests.sh deleted file mode 100755 index c80efed6c377..000000000000 --- a/ci/docker/install/ubuntu_nightly_tests.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -#Install steps for the nightly tests - -set -ex - -# Install for Compilation warning Nightly Test -# Adding ppas frequently fails due to busy gpg servers, retry 5 times with 5 minute delays. -for i in 1 2 3 4 5; do add-apt-repository -y ppa:ubuntu-toolchain-r/test && break || sleep 300; done - -apt-get update || true -apt-get -y install time - -# Install for RAT License Check Nightly Test -apt-get install -y subversion maven -y #>/dev/null - -# Packages needed for the Straight Dope Nightly tests. -pip3 install pandas scikit-image prompt_toolkit diff --git a/ci/docker/install/ubuntu_r.sh b/ci/docker/install/ubuntu_r.sh deleted file mode 100755 index 44ebf7c0799e..000000000000 --- a/ci/docker/install/ubuntu_r.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -# Important Maintenance Instructions: -# Align changes with installation instructions in /get_started/ubuntu_setup.md -# Align with R install script: /docs/install/install_mxnet_ubuntu_r.sh - -set -ex -cd "$(dirname "$0")" -# install libraries for mxnet's r package on ubuntu -echo "deb http://cran.rstudio.com/bin/linux/ubuntu trusty/" >> /etc/apt/sources.list - -apt-key add r.gpg - -# Installing the latest version (3.3+) that is compatible with MXNet -add-apt-repository 'deb [arch=amd64,i386] https://cran.rstudio.com/bin/linux/ubuntu xenial/' - -apt-get update || true -apt-get install -y --allow-unauthenticated \ - libcairo2-dev \ - libssl-dev \ - libxml2-dev \ - libxt-dev \ - r-base \ - r-base-dev \ - texinfo \ - texlive \ - texlive-fonts-extra - -# Delete cran repository as it requires --allow-unauthenticated -find /etc/apt -name "*.list" | xargs sed -i 's/.*cran\.rstudio.com.*//' diff --git a/ci/docker/install/ubuntu_rat.sh b/ci/docker/install/ubuntu_rat.sh deleted file mode 100755 index 2c905fc275c7..000000000000 --- a/ci/docker/install/ubuntu_rat.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -set -ex - -echo "Install dependencies" -apt-get update || true -apt-get install -y subversion maven openjdk-8-jdk openjdk-8-jre - -echo "download RAT" -#svn co http://svn.apache.org/repos/asf/creadur/rat/trunk/ -svn co http://svn.apache.org/repos/asf/creadur/rat/branches/0.12-release/ - -echo "cd into directory" -cd 0.12-release - -echo "mvn install" -mvn -Dmaven.test.skip=true install diff --git a/ci/docker/install/ubuntu_scala.sh b/ci/docker/install/ubuntu_scala.sh deleted file mode 100755 index 355e978e075c..000000000000 --- a/ci/docker/install/ubuntu_scala.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -# build and install are separated so changes to build don't invalidate -# the whole docker cache for the image - -set -ex - -apt-get update || true -apt-get install -y \ - openjdk-8-jdk \ - openjdk-8-jre \ - software-properties-common \ - scala \ - maven diff --git a/ci/docker/runtime_functions.sh b/ci/docker/runtime_functions.sh index 666c59e6e4aa..76b723c5d919 100755 --- a/ci/docker/runtime_functions.sh +++ b/ci/docker/runtime_functions.sh @@ -58,58 +58,6 @@ EOF fi } -build_ccache_wrappers() { - set -ex - - if [ -z ${CC+x} ]; then - echo "No \$CC set, defaulting to gcc"; - export CC=gcc - fi - if [ -z ${CXX+x} ]; then - echo "No \$CXX set, defaulting to g++"; - export CXX=g++ - fi - - # Recommended by CCache: https://ccache.samba.org/manual.html#_run_modes - # Add to the beginning of path to ensure this redirection is picked up instead - # of the original ones. Especially CUDA/NVCC appends itself to the beginning of the - # path and thus this redirect is ignored. This change fixes this problem - # This hacky approach with symbolic links is required because underlying build - # systems of our submodules ignore our CMake settings. If they use Makefile, - # we can't influence them at all in general and NVCC also prefers to hardcode their - # compiler instead of respecting the settings. Thus, we take this brutal approach - # and just redirect everything of this installer has been called. - # In future, we could do these links during image build time of the container. - # But in the beginning, we'll make this opt-in. In future, loads of processes like - # the scala make step or numpy compilation and other pip package generations - # could be heavily sped up by using ccache as well. - mkdir -p /tmp/ccache-redirects - export PATH=/tmp/ccache-redirects:$PATH - CCACHE=`which ccache` - ln -sf $CCACHE /tmp/ccache-redirects/gcc - ln -sf $CCACHE /tmp/ccache-redirects/gcc-8 - ln -sf $CCACHE /tmp/ccache-redirects/g++ - ln -sf $CCACHE /tmp/ccache-redirects/g++-8 - ln -sf $CCACHE /tmp/ccache-redirects/clang++-3.9 - ln -sf $CCACHE /tmp/ccache-redirects/clang-3.9 - ln -sf $CCACHE /tmp/ccache-redirects/clang++-5.0 - ln -sf $CCACHE /tmp/ccache-redirects/clang-5.0 - ln -sf $CCACHE /tmp/ccache-redirects/clang++-6.0 - ln -sf $CCACHE /tmp/ccache-redirects/clang-6.0 - ln -sf $CCACHE /tmp/ccache-redirects/clang++-10 - ln -sf $CCACHE /tmp/ccache-redirects/clang-10 - #Doesn't work: https://github.com/ccache/ccache/issues/373 - # ln -sf $CCACHE /tmp/ccache-redirects/nvcc - # ln -sf $CCACHE /tmp/ccache-redirects/nvcc - # export NVCC="/tmp/ccache-redirects/nvcc" - - # Uncomment if you would like to debug CCache hit rates. - # You can monitor using tail -f ccache-log - #export CCACHE_LOGFILE=/work/mxnet/ccache-log - #export CCACHE_LOGFILE=/tmp/ccache-log - #export CCACHE_DEBUG=1 -} - build_wheel() { set -ex @@ -321,21 +269,6 @@ build_centos7_cpu() { ninja } -build_centos7_cpu_make() { - set -ex - cd /work/mxnet - source /opt/rh/devtoolset-7/enable - make \ - DEV=1 \ - USE_LAPACK=1 \ - USE_LAPACK_PATH=/usr/lib64/liblapack.so \ - USE_BLAS=openblas \ - USE_MKLDNN=0 \ - USE_DIST_KVSTORE=1 \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) -} - build_centos7_mkldnn() { set -ex cd /work/build @@ -384,30 +317,12 @@ build_ubuntu_cpu_openblas() { ninja } -build_ubuntu_cpu_openblas_make() { - set -ex - export CC=gcc-7 - export CXX=g++-7 - build_ccache_wrappers - make \ - DEV=1 \ - USE_TVM_OP=1 \ - USE_CPP_PACKAGE=1 \ - USE_BLAS=openblas \ - USE_MKLDNN=0 \ - USE_DIST_KVSTORE=1 \ - USE_LIBJPEG_TURBO=1 \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) - make cython PYTHON=python3 -} - build_ubuntu_cpu_mkl() { set -ex cd /work/build CC=gcc-7 CXX=g++-7 cmake \ -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ - -DENABLE_TESTCOVERAGE=ON \ + -DENABLE_TESTCOVERAGE=OFF \ -DUSE_MKLDNN=OFF \ -DUSE_CUDA=OFF \ -DUSE_TVM_OP=ON \ @@ -547,9 +462,8 @@ build_ubuntu_cpu_clang100() { build_ubuntu_cpu_clang_tidy() { set -ex cd /work/build - export CLANG_TIDY=/usr/lib/llvm-6.0/share/clang/run-clang-tidy.py # TODO(leezu) USE_OPENMP=OFF 3rdparty/dmlc-core/CMakeLists.txt:79 broken? - CXX=clang++-6.0 CC=clang-6.0 cmake \ + CXX=clang++-10 CC=clang-10 cmake \ -DUSE_MKL_IF_AVAILABLE=OFF \ -DUSE_MKLDNN=OFF \ -DUSE_CUDA=OFF \ @@ -557,11 +471,9 @@ build_ubuntu_cpu_clang_tidy() { -DCMAKE_BUILD_TYPE=Debug \ -DUSE_DIST_KVSTORE=ON \ -DUSE_CPP_PACKAGE=ON \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DCMAKE_CXX_CLANG_TIDY=clang-tidy-10 \ -G Ninja /work/mxnet ninja - cd /work/mxnet - $CLANG_TIDY -p /work/build -j $(nproc) -clang-tidy-binary clang-tidy-6.0 /work/mxnet/src } build_ubuntu_cpu_clang6_mkldnn() { @@ -589,22 +501,6 @@ build_ubuntu_cpu_clang100_mkldnn() { ninja } -build_ubuntu_cpu_mkldnn_make() { - set -ex - - export CC=gcc-7 - export CXX=g++-7 - build_ccache_wrappers - - make \ - DEV=1 \ - USE_CPP_PACKAGE=1 \ - USE_TVM_OP=1 \ - USE_BLAS=openblas \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) -} - build_ubuntu_cpu_mkldnn() { set -ex cd /work/build @@ -625,7 +521,7 @@ build_ubuntu_cpu_mkldnn_mkl() { cd /work/build CC=gcc-7 CXX=g++-7 cmake \ -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ - -DENABLE_TESTCOVERAGE=ON \ + -DENABLE_TESTCOVERAGE=OFF \ -DUSE_MKLDNN=ON \ -DUSE_CUDA=OFF \ -DUSE_TVM_OP=ON \ @@ -653,17 +549,16 @@ build_ubuntu_gpu_tensorrt() { rm -rf build mkdir -p build cd build - cmake \ - -DCMAKE_CXX_FLAGS=-I/usr/include/python${PYVER}\ - -DBUILD_SHARED_LIBS=ON ..\ - -G Ninja - ninja -j 1 -v onnx/onnx.proto - ninja -j 1 -v + cmake -DBUILD_SHARED_LIBS=ON -GNinja .. + ninja onnx/onnx.proto + ninja export LIBRARY_PATH=`pwd`:`pwd`/onnx/:$LIBRARY_PATH export CPLUS_INCLUDE_PATH=`pwd`:$CPLUS_INCLUDE_PATH popd # Build ONNX-TensorRT + export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib + export CPLUS_INCLUDE_PATH=${CPLUS_INCLUDE_PATH}:/usr/local/cuda-10.1/targets/x86_64-linux/include/ pushd . cd 3rdparty/onnx-tensorrt/ mkdir -p build @@ -754,45 +649,6 @@ build_ubuntu_gpu_cuda101_cudnn7_debug() { ninja } -build_ubuntu_gpu_cuda101_cudnn7_make() { - set -ex - export CC=gcc-7 - export CXX=g++-7 - build_ccache_wrappers - make \ - USE_BLAS=openblas \ - USE_MKLDNN=0 \ - USE_CUDA=1 \ - USE_CUDA_PATH=/usr/local/cuda \ - USE_CUDNN=1 \ - USE_CPP_PACKAGE=1 \ - USE_DIST_KVSTORE=1 \ - CUDA_ARCH="$CI_CUDA_COMPUTE_CAPABILITIES" \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) - make cython PYTHON=python3 -} - -build_ubuntu_gpu_cuda101_cudnn7_mkldnn_cpp_test() { - set -ex - export CC=gcc-7 - export CXX=g++-7 - build_ccache_wrappers - make \ - USE_BLAS=openblas \ - USE_MKLDNN=1 \ - USE_CUDA=1 \ - USE_CUDA_PATH=/usr/local/cuda \ - USE_CUDNN=1 \ - USE_CPP_PACKAGE=1 \ - USE_DIST_KVSTORE=1 \ - CUDA_ARCH="$CI_CUDA_COMPUTE_CAPABILITIES" \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) - make test USE_CPP_PACKAGE=1 -j$(nproc) - make cython PYTHON=python3 -} - build_ubuntu_gpu_cmake() { set -ex cd /work/build @@ -876,11 +732,26 @@ build_ubuntu_blc() { # Testing sanity_check() { + set -ex + sanity_license + sanity_python + sanity_cpp +} + +sanity_license() { set -ex tools/license_header.py check - make cpplint - make pylint - pytest -n 4 tests/tutorials/test_sanity_tutorials.py +} + +sanity_cpp() { + set -ex + 3rdparty/dmlc-core/scripts/lint.py mxnet cpp include src plugin tests --exclude_path src/operator/contrib/ctc_include include/mkldnn +} + +sanity_python() { + set -ex + python3 -m pylint --rcfile=ci/other/pylintrc --ignore-patterns=".*\.so$$,.*\.dll$$,.*\.dylib$$" python/mxnet + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 tests/tutorials/test_sanity_tutorials.py } # Tests libmxnet @@ -899,7 +770,7 @@ cd_unittest_ubuntu() { local mxnet_variant=${1:?"This function requires a mxnet variant as the first argument"} - pytest -m 'not serial' -n 4 --durations=50 --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -n 4 --durations=50 --verbose tests/python/unittest pytest -m 'serial' --durations=50 --verbose tests/python/unittest # https://github.com/apache/incubator-mxnet/issues/11801 @@ -910,9 +781,9 @@ cd_unittest_ubuntu() { if [[ ${mxnet_variant} = cu* ]]; then MXNET_GPU_MEM_POOL_TYPE=Unpooled \ MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --verbose tests/python/gpu MXNET_GPU_MEM_POOL_TYPE=Unpooled \ - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --verbose tests/python/gpu pytest -m 'serial' --durations=50 --verbose tests/python/gpu # TODO(szha): fix and reenable the hanging issue. tracked in #18098 @@ -922,7 +793,7 @@ cd_unittest_ubuntu() { fi if [[ ${mxnet_variant} = *mkl ]]; then - pytest -n 4 --durations=50 --verbose tests/python/mkl + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 --durations=50 --verbose tests/python/mkl fi } @@ -934,24 +805,12 @@ unittest_ubuntu_python3_cpu() { export MXNET_SUBGRAPH_VERBOSE=0 export MXNET_ENABLE_CYTHON=0 export DMLC_LOG_STACK_TRACE_DEPTH=10 - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest pytest -m 'serial' --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest } -unittest_ubuntu_python3_cpu_serial() { - # TODO(szha): delete this and switch to unittest_ubuntu_python3_cpu once #18244 is fixed - set -ex - export PYTHONPATH=./python/ - export MXNET_MKLDNN_DEBUG=0 # Ignored if not present - export MXNET_STORAGE_FALLBACK_LOG_VERBOSE=0 - export MXNET_SUBGRAPH_VERBOSE=0 - export MXNET_ENABLE_CYTHON=0 - export DMLC_LOG_STACK_TRACE_DEPTH=10 - pytest --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest -} - unittest_ubuntu_python3_cpu_mkldnn() { set -ex export PYTHONPATH=./python/ @@ -960,8 +819,10 @@ unittest_ubuntu_python3_cpu_mkldnn() { export MXNET_SUBGRAPH_VERBOSE=0 export MXNET_ENABLE_CYTHON=0 export DMLC_LOG_STACK_TRACE_DEPTH=10 - # TODO(szha): enable parallel testing and naive engine for ops once #18244 is fixed - pytest --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest + MXNET_ENGINE_TYPE=NaiveEngine \ + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest + pytest -m 'serial' --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest pytest --durations=50 --cov-report xml:tests_mkl.xml --verbose tests/python/mkl } @@ -975,10 +836,10 @@ unittest_ubuntu_python3_gpu() { export MXNET_ENABLE_CYTHON=0 export DMLC_LOG_STACK_TRACE_DEPTH=10 MXNET_GPU_MEM_POOL_TYPE=Unpooled \ - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu MXNET_GPU_MEM_POOL_TYPE=Unpooled \ MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu pytest -m 'serial' --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu } @@ -994,10 +855,10 @@ unittest_ubuntu_python3_gpu_cython() { export DMLC_LOG_STACK_TRACE_DEPTH=10 check_cython MXNET_GPU_MEM_POOL_TYPE=Unpooled \ - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu MXNET_GPU_MEM_POOL_TYPE=Unpooled \ MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu pytest -m 'serial' --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu } @@ -1010,10 +871,10 @@ unittest_ubuntu_python3_gpu_nocudnn() { export MXNET_ENABLE_CYTHON=0 export DMLC_LOG_STACK_TRACE_DEPTH=10 MXNET_GPU_MEM_POOL_TYPE=Unpooled \ - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --verbose tests/python/gpu MXNET_GPU_MEM_POOL_TYPE=Unpooled \ MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu pytest -m 'serial' --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu } @@ -1026,11 +887,11 @@ unittest_centos7_cpu() { set -ex source /opt/rh/rh-python36/enable cd /work/mxnet - python -m pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) python -m pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --verbose tests/python/unittest MXNET_ENGINE_TYPE=NaiveEngine \ - python -m pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) python -m pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest python -m pytest -m 'serial' --durations=50 --cov-report xml:tests_unittest.xml --cov-append --verbose tests/python/unittest - python -m pytest -n 4 --durations=50 --cov-report xml:tests_train.xml --verbose tests/python/train + OMP_NUM_THREADS=$(expr $(nproc) / 4) python -m pytest -n 4 --durations=50 --cov-report xml:tests_train.xml --verbose tests/python/train } unittest_centos7_gpu() { @@ -1040,10 +901,10 @@ unittest_centos7_gpu() { export CUDNN_VERSION=${CUDNN_VERSION:-7.0.3} export DMLC_LOG_STACK_TRACE_DEPTH=10 MXNET_GPU_MEM_POOL_TYPE=Unpooled \ - pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu MXNET_GPU_MEM_POOL_TYPE=Unpooled \ MXNET_ENGINE_TYPE=NaiveEngine \ - pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu pytest -m 'serial' --durations=50 --cov-report xml:tests_gpu.xml --cov-append --verbose tests/python/gpu } @@ -1052,9 +913,9 @@ integrationtest_ubuntu_cpu_onnx() { export PYTHONPATH=./python/ export DMLC_LOG_STACK_TRACE_DEPTH=10 python3 tests/python/unittest/onnx/backend_test.py - pytest -n 4 tests/python/unittest/onnx/mxnet_export_test.py - pytest -n 4 tests/python/unittest/onnx/test_models.py - pytest -n 4 tests/python/unittest/onnx/test_node.py + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 tests/python/unittest/onnx/mxnet_export_test.py + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 tests/python/unittest/onnx/test_models.py + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 tests/python/unittest/onnx/test_node.py } integrationtest_ubuntu_cpu_dist_kvstore() { @@ -1130,9 +991,9 @@ test_ubuntu_cpu_python3() { cd /work/mxnet/python pip3 install -e . cd /work/mxnet - python3 -m pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) python3 -m pytest -m 'not serial' -k 'not test_operator' -n 4 --durations=50 --verbose tests/python/unittest MXNET_ENGINE_TYPE=NaiveEngine \ - python3 -m pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --verbose tests/python/unittest + OMP_NUM_THREADS=$(expr $(nproc) / 4) python3 -m pytest -m 'not serial' -k 'test_operator' -n 4 --durations=50 --verbose tests/python/unittest python3 -m pytest -m 'serial' --durations=50 --verbose tests/python/unittest popd @@ -1153,15 +1014,15 @@ unittest_ubuntu_python3_arm() { # Functions that run the nightly Tests: #Runs Apache RAT Check on MXNet Source for License Headers -nightly_test_rat_check() { +test_rat_check() { set -e pushd . - cd /work/deps/0.12-release/apache-rat/target + cd /usr/local/src/apache-rat-0.13 # Use shell number 5 to duplicate the log output. It get sprinted and stored in $OUTPUT at the same time https://stackoverflow.com/a/12451419 exec 5>&1 - OUTPUT=$(java -jar apache-rat-0.13-SNAPSHOT.jar -E /work/mxnet/tests/nightly/apache_rat_license_check/rat-excludes -d /work/mxnet|tee >(cat - >&5)) + OUTPUT=$(java -jar apache-rat-0.13.jar -E /work/mxnet/tests/nightly/apache_rat_license_check/rat-excludes -d /work/mxnet|tee >(cat - >&5)) ERROR_MESSAGE="Printing headers for text files without a valid license header" @@ -1267,25 +1128,12 @@ build_docs_setup() { } build_ubuntu_cpu_docs() { - set -ex - export CC="gcc-7" - export CXX="g++-7" - build_ccache_wrappers - make \ - DEV=1 \ - USE_CPP_PACKAGE=1 \ - USE_BLAS=openblas \ - USE_MKLDNN=0 \ - USE_DIST_KVSTORE=1 \ - USE_LIBJPEG_TURBO=1 \ - USE_SIGNAL_HANDLER=1 \ - -j$(nproc) + build_ubuntu_cpu_openblas } build_jekyll_docs() { set -ex - source /etc/profile.d/rvm.sh pushd . build_docs_setup @@ -1409,8 +1257,6 @@ build_static_libmxnet() { pushd . source /opt/rh/devtoolset-7/enable source /opt/rh/rh-python36/enable - export USE_SYSTEM_CUDA=1 - export CMAKE_STATICBUILD=1 local mxnet_variant=${1:?"This function requires a python command as the first argument"} source tools/staticbuild/build.sh ${mxnet_variant} popd @@ -1484,7 +1330,6 @@ build_static_python_cu92() { set -ex pushd . export mxnet_variant=cu92 - export USE_SYSTEM_CUDA=1 source /opt/rh/devtoolset-7/enable source /opt/rh/rh-python36/enable ./ci/publish/python/build.sh @@ -1502,7 +1347,7 @@ test_artifact_repository() { set -ex pushd . cd cd/utils/ - pytest -n 4 test_artifact_repository.py + OMP_NUM_THREADS=$(expr $(nproc) / 4) pytest -n 4 test_artifact_repository.py popd } diff --git a/ci/docker/toolchains/aarch64-linux-gnu-toolchain.cmake b/ci/docker/toolchains/aarch64-linux-gnu-toolchain.cmake index 3780415c4b15..57072b5cf393 100644 --- a/ci/docker/toolchains/aarch64-linux-gnu-toolchain.cmake +++ b/ci/docker/toolchains/aarch64-linux-gnu-toolchain.cmake @@ -19,6 +19,7 @@ set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR "aarch64") set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) +set(CMAKE_CUDA_COMPILER nvcc) set(CMAKE_CUDA_HOST_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_FIND_ROOT_PATH "/usr/aarch64-linux-gnu") diff --git a/ci/docker_cache.py b/ci/docker_cache.py deleted file mode 100644 index 7fb946b53ebc..000000000000 --- a/ci/docker_cache.py +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -""" -Utility to handle distributed docker cache. This is done by keeping the entire image chain of a docker container -on an S3 bucket. This utility allows cache creation and download. After execution, the cache will be in an identical -state as if the container would have been built locally already. -""" - -import argparse -import logging -import os -import subprocess -import sys -from typing import * - -import build as build_util -from docker_login import login_dockerhub, logout_dockerhub -from util import retry - -DOCKER_CACHE_NUM_RETRIES = 3 -DOCKER_CACHE_TIMEOUT_MINS = 45 -PARALLEL_BUILDS = 10 -DOCKER_CACHE_RETRY_SECONDS = 5 - - -def build_save_containers(platforms, registry, load_cache, no_publish) -> int: - """ - Entry point to build and upload all built dockerimages in parallel - :param platforms: List of platforms - :param registry: Docker registry name - :param load_cache: Load cache before building - :return: 1 if error occurred, 0 otherwise - """ - from joblib import Parallel, delayed - if len(platforms) == 0: - return 0 - - platform_results = Parallel(n_jobs=PARALLEL_BUILDS, backend="multiprocessing")( - delayed(_build_save_container)(platform, registry, load_cache, no_publish) - for platform in platforms) - - is_error = False - for platform_result in platform_results: - if platform_result is not None: - logging.error('Failed to generate %s', platform_result) - is_error = True - - return 1 if is_error else 0 - - -def _build_save_container(platform, registry, load_cache, no_publish) -> Optional[str]: - """ - Build image for passed platform and upload the cache to the specified S3 bucket - :param platform: Platform - :param registry: Docker registry name - :param load_cache: Load cache before building - :return: Platform if failed, None otherwise - """ - docker_tag = build_util.get_docker_tag(platform=platform, registry=registry) - # Preload cache - if load_cache: - load_docker_cache(registry=registry, docker_tag=docker_tag) - - # Start building - logging.debug('Building %s as %s', platform, docker_tag) - try: - # Increase the number of retries for building the cache. - image_id = build_util.build_docker(platform=platform, registry=registry, num_retries=10, no_cache=False) - logging.info('Built %s as %s', docker_tag, image_id) - - # Push cache to registry - if not no_publish: - _upload_image(registry=registry, docker_tag=docker_tag, image_id=image_id) - return None - except Exception: - logging.exception('Unexpected exception during build of %s', docker_tag) - return platform - # Error handling is done by returning the errorous platform name. This is necessary due to - # Parallel being unable to handle exceptions - - -def _upload_image(registry, docker_tag, image_id) -> None: - """ - Upload the passed image by id, tag it with docker tag and upload to S3 bucket - :param registry: Docker registry name - :param docker_tag: Docker tag - :param image_id: Image id - :return: None - """ - # We don't have to retag the image since it is already in the right format - logging.info('Uploading %s (%s) to %s', docker_tag, image_id, registry) - push_cmd = ['docker', 'push', docker_tag] - subprocess.check_call(push_cmd) - - -@retry(target_exception=subprocess.TimeoutExpired, tries=DOCKER_CACHE_NUM_RETRIES, - delay_s=DOCKER_CACHE_RETRY_SECONDS) -def load_docker_cache(registry, docker_tag) -> None: - """ - Load the precompiled docker cache from the registry - :param registry: Docker registry name - :param docker_tag: Docker tag to load - :return: None - """ - # We don't have to retag the image since it's already in the right format - if not registry: - return - assert docker_tag - - logging.info('Loading Docker cache for %s from %s', docker_tag, registry) - pull_cmd = ['docker', 'pull', docker_tag] - - # Don't throw an error if the image does not exist - subprocess.run(pull_cmd, timeout=DOCKER_CACHE_TIMEOUT_MINS*60) - logging.info('Successfully pulled docker cache') - - -def delete_local_docker_cache(docker_tag): - """ - Delete the local docker cache for the entire docker image chain - :param docker_tag: Docker tag - :return: None - """ - history_cmd = ['docker', 'history', '-q', docker_tag] - - try: - image_ids_b = subprocess.check_output(history_cmd) - image_ids_str = image_ids_b.decode('utf-8').strip() - layer_ids = [id.strip() for id in image_ids_str.split('\n') if id != ''] - - delete_cmd = ['docker', 'image', 'rm', '--force'] - delete_cmd.extend(layer_ids) - subprocess.check_call(delete_cmd) - except subprocess.CalledProcessError as error: - # Could be caused by the image not being present - logging.debug('Error during local cache deletion %s', error) - - -def main() -> int: - """ - Utility to create and publish the Docker cache to Docker Hub - :return: - """ - # We need to be in the same directory than the script so the commands in the dockerfiles work as - # expected. But the script can be invoked from a different path - base = os.path.split(os.path.realpath(__file__))[0] - os.chdir(base) - - logging.getLogger().setLevel(logging.DEBUG) - logging.getLogger('botocore').setLevel(logging.INFO) - logging.getLogger('boto3').setLevel(logging.INFO) - logging.getLogger('urllib3').setLevel(logging.INFO) - logging.getLogger('s3transfer').setLevel(logging.INFO) - - def script_name() -> str: - return os.path.split(sys.argv[0])[1] - - logging.basicConfig(format='{}: %(asctime)-15s %(message)s'.format(script_name())) - - parser = argparse.ArgumentParser(description="Utility for preserving and loading Docker cache", epilog="") - parser.add_argument("--docker-registry", - help="Docker hub registry name", - type=str, - required=True) - parser.add_argument("--no-publish", help="Only build but don't publish. Used for testing.", - action='store_true') - - args = parser.parse_args() - - platforms = build_util.get_platforms(legacy_only=True) - - secret_name = os.environ['DOCKERHUB_SECRET_NAME'] - endpoint_url = os.environ['DOCKERHUB_SECRET_ENDPOINT_URL'] - region_name = os.environ['DOCKERHUB_SECRET_ENDPOINT_REGION'] - - try: - if not args.no_publish: - login_dockerhub(secret_name, endpoint_url, region_name) - return build_save_containers(platforms=platforms, registry=args.docker_registry, load_cache=True, no_publish=args.no_publish) - finally: - logout_dockerhub() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/ci/docker_cache_requirements b/ci/docker_cache_requirements deleted file mode 100644 index d1272cb348c7..000000000000 --- a/ci/docker_cache_requirements +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. -boto3==1.7.13 -botocore==1.10.13 -docutils==0.14 -jmespath==0.9.3 -joblib==0.11 -python-dateutil==2.7.2 -s3transfer==0.1.13 -six==1.11.0 diff --git a/ci/jenkins/Jenkins_steps.groovy b/ci/jenkins/Jenkins_steps.groovy index 923d41b4c383..8079420dd794 100644 --- a/ci/jenkins/Jenkins_steps.groovy +++ b/ci/jenkins/Jenkins_steps.groovy @@ -25,7 +25,6 @@ utils = load('ci/Jenkinsfile_utils.groovy') // mxnet libraries mx_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, build/3rdparty/openmp/runtime/src/libomp.so' mx_lib_cython = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, python/mxnet/_cy3/*.so, build/3rdparty/openmp/runtime/src/libomp.so, python/mxnet/_ffi/_cy3/*.so' -mx_lib_make = 'lib/libmxnet.so, lib/libmxnet.a, lib/libtvm_runtime.so, lib/libtvmop.so, lib/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, 3rdparty/dmlc-core/libdmlc.a, 3rdparty/tvm/nnvm/lib/libnnvm.a' // mxnet cmake libraries, in cmake builds we do not produce a libnvvm static library by default. mx_cmake_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/tests/mxnet_unit_tests, build/3rdparty/openmp/runtime/src/libomp.so' @@ -34,11 +33,8 @@ mx_cmake_lib_cython = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, // mxnet cmake libraries, in cmake builds we do not produce a libnvvm static library by default. mx_cmake_lib_debug = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, build/tests/mxnet_unit_tests' mx_mkldnn_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/3rdparty/openmp/runtime/src/libomp.so, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so' -mx_mkldnn_lib_make = 'lib/libmxnet.so, lib/libmxnet.a, lib/libtvm_runtime.so, lib/libtvmop.so, lib/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, 3rdparty/dmlc-core/libdmlc.a, 3rdparty/tvm/nnvm/lib/libnnvm.a' mx_tensorrt_lib = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/3rdparty/openmp/runtime/src/libomp.so, lib/libnvonnxparser_runtime.so.0, lib/libnvonnxparser.so.0, lib/libonnx_proto.so, lib/libonnx.so' mx_lib_cpp_examples = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/3rdparty/openmp/runtime/src/libomp.so, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so' -mx_lib_cpp_examples_make = 'lib/libmxnet.so, lib/libmxnet.a, lib/libtvm_runtime.so, lib/libtvmop.so, lib/tvmop.conf, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, 3rdparty/dmlc-core/libdmlc.a, 3rdparty/tvm/nnvm/lib/libnnvm.a, 3rdparty/ps-lite/build/libps.a, deps/lib/libprotobuf-lite.a, deps/lib/libzmq.a, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so' -mx_lib_cpp_capi_make = 'lib/libmxnet.so, lib/libmxnet.a, lib/libtvm_runtime.so, lib/libtvmop.so, lib/tvmop.conf, libsample_lib.so, lib/libmkldnn.so.1, lib/libmklml_intel.so, 3rdparty/dmlc-core/libdmlc.a, 3rdparty/tvm/nnvm/lib/libnnvm.a, 3rdparty/ps-lite/build/libps.a, deps/lib/libprotobuf-lite.a, deps/lib/libzmq.a, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so, build/tests/cpp/mxnet_unit_tests' mx_lib_cpp_examples_no_tvm_op = 'build/libmxnet.so, build/libcustomop_lib.so, build/libcustomop_gpu_lib.so, build/libsubgraph_lib.so, build/3rdparty/openmp/runtime/src/libomp.so, python/mxnet/_cy3/*.so, python/mxnet/_ffi/_cy3/*.so' mx_lib_cpp_examples_cpu = 'build/libmxnet.so, build/3rdparty/tvm/libtvm_runtime.so, build/libtvmop.so, build/tvmop.conf, build/3rdparty/openmp/runtime/src/libomp.so' mx_cd_lib = 'lib/libmxnet.so, licenses/*, lib/libgfortran.so.4, lib/libquadmath.so.0, lib/libopenblas.so.0, include/mkldnn/dnnl_version.h, include/mkldnn/dnnl_config.h' @@ -51,12 +47,6 @@ def python3_ut(docker_container_name) { } } -def python3_ut_serial(docker_container_name) { - timeout(time: max_time, unit: 'MINUTES') { - utils.docker_run(docker_container_name, 'unittest_ubuntu_python3_cpu_serial', false) - } -} - def python3_ut_mkldnn(docker_container_name) { timeout(time: max_time, unit: 'MINUTES') { utils.docker_run(docker_container_name, 'unittest_ubuntu_python3_cpu_mkldnn', false) @@ -101,20 +91,6 @@ def compile_unix_cpu_openblas(lib_name) { }] } -def compile_unix_cpu_openblas_make(lib_name) { - return ['CPU: Openblas Makefile': { - node(NODE_LINUX_CPU) { - ws('workspace/build-cpu-openblas') { - timeout(time: max_time, unit: 'MINUTES') { - utils.init_git() - utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_openblas_make', false) - utils.pack_lib(lib_name, mx_lib_make) - } - } - } - }] -} - def compile_unix_openblas_debug_cpu(lib_name) { return ['CPU: Openblas, cmake, debug': { node(NODE_LINUX_CPU) { @@ -177,7 +153,7 @@ def compile_unix_mkl_cpu(lib_name) { timeout(time: max_time, unit: 'MINUTES') { utils.init_git() utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_mkl', false) - utils.pack_lib(lib_name, mx_lib, true) + utils.pack_lib(lib_name, mx_lib, false) } } } @@ -198,20 +174,6 @@ def compile_unix_mkldnn_cpu(lib_name) { }] } -def compile_unix_mkldnn_cpu_make(lib_name) { - return ['CPU: MKLDNN Makefile': { - node(NODE_LINUX_CPU) { - ws('workspace/build-mkldnn-cpu') { - timeout(time: max_time, unit: 'MINUTES') { - utils.init_git() - utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_mkldnn_make', false) - utils.pack_lib(lib_name, mx_mkldnn_lib_make) - } - } - } - }] -} - def compile_unix_mkldnn_mkl_cpu(lib_name) { return ['CPU: MKLDNN_MKL': { node(NODE_LINUX_CPU) { @@ -219,7 +181,7 @@ def compile_unix_mkldnn_mkl_cpu(lib_name) { timeout(time: max_time, unit: 'MINUTES') { utils.init_git() utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_mkldnn_mkl', false) - utils.pack_lib(lib_name, mx_mkldnn_lib, true) + utils.pack_lib(lib_name, mx_mkldnn_lib, false) } } } @@ -268,21 +230,6 @@ def compile_unix_full_gpu(lib_name) { }] } -def compile_unix_full_gpu_make(lib_name) { - return ['GPU: CUDA10.1+cuDNN7 Makefile': { - node(NODE_LINUX_CPU) { - ws('workspace/build-gpu') { - timeout(time: max_time, unit: 'MINUTES') { - utils.init_git() - utils.docker_run('ubuntu_build_cuda', 'build_ubuntu_gpu_cuda101_cudnn7_make', false) - utils.pack_lib(lib_name, mx_lib_cpp_examples_make) - } - } - } - }] -} - - def compile_unix_full_gpu_debug(lib_name) { return ['GPU: CUDA10.1+cuDNN7, debug': { node(NODE_LINUX_CPU) { @@ -297,20 +244,6 @@ def compile_unix_full_gpu_debug(lib_name) { }] } -def compile_unix_full_gpu_mkldnn_cpp_test(lib_name) { - return ['GPU: CUDA10.1+cuDNN7+MKLDNN+CPPTEST Makefile': { - node(NODE_LINUX_CPU) { - ws('workspace/build-gpu-mkldnn-cpp') { - timeout(time: max_time, unit: 'MINUTES') { - utils.init_git() - utils.docker_run('ubuntu_build_cuda', 'build_ubuntu_gpu_cuda101_cudnn7_mkldnn_cpp_test', false) - utils.pack_lib(lib_name, mx_lib_cpp_capi_make) - } - } - } - }] -} - def compile_unix_cmake_gpu(lib_name) { return ['GPU: CMake': { node(NODE_LINUX_CPU) { @@ -345,7 +278,7 @@ def compile_unix_tensorrt_gpu(lib_name) { ws('workspace/build-tensorrt') { timeout(time: max_time, unit: 'MINUTES') { utils.init_git() - utils.docker_run('ubuntu_gpu_tensorrt', 'build_ubuntu_gpu_tensorrt', false) + utils.docker_run('ubuntu_gpu_cu101', 'build_ubuntu_gpu_tensorrt', false) utils.pack_lib(lib_name, mx_tensorrt_lib) } } @@ -367,20 +300,6 @@ def compile_centos7_cpu(lib_name) { }] } -def compile_centos7_cpu_make(lib_name) { - return ['CPU: CentOS 7 Makefile': { - node(NODE_LINUX_CPU) { - ws('workspace/build-centos7-cpu') { - timeout(time: max_time, unit: 'MINUTES') { - utils.init_git() - utils.docker_run('centos7_cpu', 'build_centos7_cpu_make', false) - utils.pack_lib(lib_name, mx_lib_make) - } - } - } - }] -} - def compile_centos7_cpu_mkldnn() { return ['CPU: CentOS 7 MKLDNN': { node(NODE_LINUX_CPU) { @@ -772,8 +691,8 @@ def test_unix_python3_mkl_cpu(lib_name) { node(NODE_LINUX_CPU) { ws('workspace/ut-python3-cpu') { try { - utils.unpack_and_init(lib_name, mx_lib, true) - python3_ut_serial('ubuntu_cpu') + utils.unpack_and_init(lib_name, mx_lib) + python3_ut('ubuntu_cpu') utils.publish_test_coverage() } finally { utils.collect_test_results_unix('tests_unittest.xml', 'tests_python3_cpu_unittest.xml') @@ -854,7 +773,7 @@ def test_unix_python3_mkldnn_mkl_cpu(lib_name) { node(NODE_LINUX_CPU) { ws('workspace/ut-python3-mkldnn-mkl-cpu') { try { - utils.unpack_and_init(lib_name, mx_lib, true) + utils.unpack_and_init(lib_name, mx_lib) python3_ut_mkldnn('ubuntu_cpu') utils.publish_test_coverage() } finally { @@ -903,7 +822,7 @@ def test_unix_onnx_cpu(lib_name) { node(NODE_LINUX_CPU) { ws('workspace/it-onnx-cpu') { timeout(time: max_time, unit: 'MINUTES') { - utils.unpack_and_init(lib_name, mx_lib_make) + utils.unpack_and_init(lib_name, mx_lib) utils.docker_run('ubuntu_cpu', 'integrationtest_ubuntu_cpu_onnx', false) utils.publish_test_coverage() } @@ -1132,8 +1051,8 @@ def compile_unix_lite(lib_name) { ws('workspace/docs') { timeout(time: max_time, unit: 'MINUTES') { utils.init_git() - utils.docker_run('ubuntu_cpu_lite', 'build_ubuntu_cpu_docs', false) - utils.pack_lib(lib_name, 'lib/libmxnet.so', false) + utils.docker_run('ubuntu_cpu', 'build_ubuntu_cpu_docs', false) + utils.pack_lib(lib_name, mx_lib, false) } } } @@ -1161,7 +1080,7 @@ def docs_python(lib_name) { node(NODE_LINUX_CPU) { ws('workspace/docs') { timeout(time: max_time, unit: 'MINUTES') { - utils.unpack_and_init(lib_name, 'lib/libmxnet.so', false) + utils.unpack_and_init(lib_name, mx_lib, false) utils.docker_run('ubuntu_cpu_python', 'build_python_docs', false) if (should_pack_website()) { utils.pack_lib('python-artifacts', 'docs/_build/python-artifacts.tgz', false) @@ -1309,7 +1228,7 @@ def sanity_rat_license() { node(NODE_LINUX_CPU) { ws('workspace/sanity-rat') { utils.init_git() - utils.docker_run('ubuntu_rat', 'nightly_test_rat_check', false) + utils.docker_run('ubuntu_cpu', 'test_rat_check', false) } } }] @@ -1331,7 +1250,6 @@ def misc_test_docker_cache_build() { node(NODE_LINUX_CPU) { ws('workspace/docker_cache') { utils.init_git() - sh "python3 ./ci/docker_cache.py --docker-registry ${env.DOCKER_CACHE_REGISTRY} --no-publish" sh "cd ci && docker-compose -f docker/docker-compose.yml pull && docker-compose -f docker/docker-compose.yml build --parallel" } } diff --git a/ci/jenkins/Jenkinsfile_centos_cpu b/ci/jenkins/Jenkinsfile_centos_cpu index f652478a6f32..cddb3c977a5d 100644 --- a/ci/jenkins/Jenkinsfile_centos_cpu +++ b/ci/jenkins/Jenkinsfile_centos_cpu @@ -35,7 +35,6 @@ utils.main_wrapper( core_logic: { utils.parallel_stage('Build', [ custom_steps.compile_centos7_cpu('centos7_cpu'), - custom_steps.compile_centos7_cpu_make('centos7_cpu_make'), custom_steps.compile_centos7_cpu_mkldnn(), custom_steps.compile_static_python_cpu(), custom_steps.compile_static_cd_cpu('centos7_cpu_cd') diff --git a/ci/jenkins/Jenkinsfile_unix_cpu b/ci/jenkins/Jenkinsfile_unix_cpu index 0909fc5139fe..67d5afc4cc76 100644 --- a/ci/jenkins/Jenkinsfile_unix_cpu +++ b/ci/jenkins/Jenkinsfile_unix_cpu @@ -35,11 +35,9 @@ utils.main_wrapper( core_logic: { utils.parallel_stage('Build', [ custom_steps.compile_unix_cpu_openblas('cpu'), - custom_steps.compile_unix_cpu_openblas_make('cpu_make'), custom_steps.compile_unix_openblas_debug_cpu('cpu_debug'), custom_steps.compile_unix_mkl_cpu('cpu_mkl'), custom_steps.compile_unix_mkldnn_cpu('mkldnn_cpu'), - custom_steps.compile_unix_mkldnn_cpu_make('mkldnn_cpu_make'), custom_steps.compile_unix_mkldnn_mkl_cpu('mkldnn_mkl_cpu'), custom_steps.compile_unix_int64_cpu('ubuntu_cpu'), custom_steps.compile_unix_openblas_cpu_no_tvm_op('cpu_openblas_no_tvm_op'), @@ -50,7 +48,7 @@ core_logic: { custom_steps.test_unix_python3_mkl_cpu('cpu_mkl'), custom_steps.test_unix_python3_mkldnn_cpu('mkldnn_cpu'), custom_steps.test_unix_python3_mkldnn_mkl_cpu('mkldnn_mkl_cpu'), - custom_steps.test_unix_onnx_cpu('cpu_make'), + custom_steps.test_unix_onnx_cpu('cpu'), /* Disabled due to master build failure: * http://jenkins.mxnet-ci.amazon-ml.com/blue/organizations/jenkins/incubator-mxnet/detail/master/1221/pipeline/ * https://github.com/apache/incubator-mxnet/issues/11801 diff --git a/ci/jenkins/Jenkinsfile_unix_gpu b/ci/jenkins/Jenkinsfile_unix_gpu index 1fe96bf690df..1fcdc96f46ac 100644 --- a/ci/jenkins/Jenkinsfile_unix_gpu +++ b/ci/jenkins/Jenkinsfile_unix_gpu @@ -37,13 +37,11 @@ core_logic: { custom_steps.compile_unix_mkldnn_gpu('mkldnn_gpu'), custom_steps.compile_unix_mkldnn_nocudnn_gpu('mkldnn_gpu_nocudnn'), custom_steps.compile_unix_full_gpu('gpu'), - custom_steps.compile_unix_full_gpu_make('gpu_make'), custom_steps.compile_unix_full_gpu_debug('gpu_debug'), custom_steps.compile_unix_cmake_gpu('cmake_gpu'), custom_steps.compile_unix_tensorrt_gpu('tensorrt'), custom_steps.compile_unix_int64_gpu('gpu_int64'), custom_steps.compile_unix_cmake_gpu_no_rtc('gpu_no_rtc'), - custom_steps.compile_unix_full_gpu_mkldnn_cpp_test('gpu_mkldnn_cpp_test_make') ]) utils.parallel_stage('Tests', [ diff --git a/ci/jenkins/Jenkinsfile_website_c_docs b/ci/jenkins/Jenkinsfile_website_c_docs deleted file mode 100644 index caddbae8c620..000000000000 --- a/ci/jenkins/Jenkinsfile_website_c_docs +++ /dev/null @@ -1,48 +0,0 @@ -// -*- mode: groovy -*- - -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. -// -// Jenkins pipeline -// See documents at https://jenkins.io/doc/book/pipeline/jenkinsfile/ - -// timeout in minutes -max_time = 20 - -node('utility') { - // Loading the utilities requires a node context unfortunately - checkout scm - utils = load('ci/Jenkinsfile_utils.groovy') - custom_steps = load('ci/jenkins/Jenkins_steps.groovy') -} -utils.assign_node_labels(utility: 'utility', linux_cpu: 'mxnetlinux-cpu') - -utils.main_wrapper( -core_logic: { - utils.parallel_stage('Build', [ - custom_steps.compile_unix_lite('libmxnet') - ]) - -} -, -failure_handler: { - // Only send email if master or release branches failed - if (currentBuild.result == "FAILURE" && (env.BRANCH_NAME == "master" || env.BRANCH_NAME.startsWith("v"))) { - emailext body: 'Build for MXNet branch ${BRANCH_NAME} has broken. Please view the build at ${BUILD_URL}', replyTo: '${EMAIL}', subject: '[BUILD FAILED] Branch ${BRANCH_NAME} build ${BUILD_NUMBER}', to: '${EMAIL}' - } -} -) diff --git a/ci/jenkins/Jenkinsfile_website_clojure_docs b/ci/jenkins/Jenkinsfile_website_clojure_docs deleted file mode 100644 index caddbae8c620..000000000000 --- a/ci/jenkins/Jenkinsfile_website_clojure_docs +++ /dev/null @@ -1,48 +0,0 @@ -// -*- mode: groovy -*- - -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. -// -// Jenkins pipeline -// See documents at https://jenkins.io/doc/book/pipeline/jenkinsfile/ - -// timeout in minutes -max_time = 20 - -node('utility') { - // Loading the utilities requires a node context unfortunately - checkout scm - utils = load('ci/Jenkinsfile_utils.groovy') - custom_steps = load('ci/jenkins/Jenkins_steps.groovy') -} -utils.assign_node_labels(utility: 'utility', linux_cpu: 'mxnetlinux-cpu') - -utils.main_wrapper( -core_logic: { - utils.parallel_stage('Build', [ - custom_steps.compile_unix_lite('libmxnet') - ]) - -} -, -failure_handler: { - // Only send email if master or release branches failed - if (currentBuild.result == "FAILURE" && (env.BRANCH_NAME == "master" || env.BRANCH_NAME.startsWith("v"))) { - emailext body: 'Build for MXNet branch ${BRANCH_NAME} has broken. Please view the build at ${BUILD_URL}', replyTo: '${EMAIL}', subject: '[BUILD FAILED] Branch ${BRANCH_NAME} build ${BUILD_NUMBER}', to: '${EMAIL}' - } -} -) diff --git a/ci/jenkins/Jenkinsfile_website_java_docs b/ci/jenkins/Jenkinsfile_website_java_docs deleted file mode 100644 index 03d160009740..000000000000 --- a/ci/jenkins/Jenkinsfile_website_java_docs +++ /dev/null @@ -1,47 +0,0 @@ -// -*- mode: groovy -*- - -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. -// -// Jenkins pipeline -// See documents at https://jenkins.io/doc/book/pipeline/jenkinsfile/ - -// timeout in minutes -max_time = 20 - -node('utility') { - // Loading the utilities requires a node context unfortunately - checkout scm - utils = load('ci/Jenkinsfile_utils.groovy') - custom_steps = load('ci/jenkins/Jenkins_steps.groovy') -} -utils.assign_node_labels(utility: 'utility', linux_cpu: 'mxnetlinux-cpu') - -utils.main_wrapper( -core_logic: { - utils.parallel_stage('Build', [ - custom_steps.compile_unix_lite('libmxnet') - ]) -} -, -failure_handler: { - // Only send email if master or release branches failed - if (currentBuild.result == "FAILURE" && (env.BRANCH_NAME == "master" || env.BRANCH_NAME.startsWith("v"))) { - emailext body: 'Build for MXNet branch ${BRANCH_NAME} has broken. Please view the build at ${BUILD_URL}', replyTo: '${EMAIL}', subject: '[BUILD FAILED] Branch ${BRANCH_NAME} build ${BUILD_NUMBER}', to: '${EMAIL}' - } -} -) diff --git a/ci/jenkins/Jenkinsfile_website_julia_docs b/ci/jenkins/Jenkinsfile_website_julia_docs deleted file mode 100644 index 8a2528f89ce7..000000000000 --- a/ci/jenkins/Jenkinsfile_website_julia_docs +++ /dev/null @@ -1,48 +0,0 @@ -// -*- mode: groovy -*- - -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. -// -// Jenkins pipeline -// See documents at https://jenkins.io/doc/book/pipeline/jenkinsfile/ - -// timeout in minutes -max_time = 60 - -node('utility') { - // Loading the utilities requires a node context unfortunately - checkout scm - utils = load('ci/Jenkinsfile_utils.groovy') - custom_steps = load('ci/jenkins/Jenkins_steps.groovy') -} -utils.assign_node_labels(utility: 'utility', linux_cpu: 'mxnetlinux-cpu') - -utils.main_wrapper( -core_logic: { - utils.parallel_stage('Build', [ - custom_steps.compile_unix_lite('libmxnet') - ]) - -} -, -failure_handler: { - // Only send email if master or release branches failed - if (currentBuild.result == "FAILURE" && (env.BRANCH_NAME == "master" || env.BRANCH_NAME.startsWith("v"))) { - emailext body: 'Build for MXNet branch ${BRANCH_NAME} has broken. Please view the build at ${BUILD_URL}', replyTo: '${EMAIL}', subject: '[BUILD FAILED] Branch ${BRANCH_NAME} build ${BUILD_NUMBER}', to: '${EMAIL}' - } -} -) diff --git a/ci/test_docker_cache.py b/ci/test_docker_cache.py deleted file mode 100644 index 81b315be4cff..000000000000 --- a/ci/test_docker_cache.py +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -""" -Distributed Docker cache tests -""" - -import unittest.mock -import tempfile -import os -import logging -import subprocess -import sys -from unittest.mock import MagicMock - -sys.path.append(os.path.dirname(__file__)) -import docker_cache -import build as build_util - -DOCKERFILE_DIR = 'docker' -DOCKER_REGISTRY_NAME = 'test_registry' -DOCKER_REGISTRY_PORT = 5000 -DOCKER_REGISTRY_PATH = 'localhost:{}'.format(DOCKER_REGISTRY_PORT) - -class RedirectSubprocessOutput(object): - """ - Redirect the output of all subprocess.call calls to a readable buffer instead of writing it to stdout/stderr. - The output can then be retrieved with get_output. - """ - def __enter__(self): - self.buf_output = tempfile.TemporaryFile() - - def trampoline(*popenargs, **kwargs): - self.call(*popenargs, **kwargs) - - self.old_method = subprocess.call - subprocess.call = trampoline - return self - - def __exit__(self, *args): - logging.info('Releasing docker output buffer:\n%s', self.get_output()) - subprocess.call = self.old_method - self.buf_output.close() - - def call(self, *popenargs, **kwargs): - """ - Replace subprocess.call - :param popenargs: - :param timeout: - :param kwargs: - :return: - """ - kwargs['stderr'] = subprocess.STDOUT - kwargs['stdout'] = self.buf_output - return self.old_method(*popenargs, **kwargs) - - def get_output(self): - self.buf_output.seek(0) - return self.buf_output.read().decode('utf-8') - - -class TestDockerCache(unittest.TestCase): - """ - Test utility class - """ - def setUp(self): - logging.getLogger().setLevel(logging.DEBUG) - - # We need to be in the same directory than the script so the commands in the dockerfiles work as - # expected. But the script can be invoked from a different path - base = os.path.split(os.path.realpath(__file__))[0] - os.chdir(base) - - docker_cache.login_dockerhub = MagicMock() # Override login - - # Stop in case previous execution was dirty - try: - self._stop_local_docker_registry() - except Exception: - pass - - # Start up docker registry - self._start_local_docker_registry() - - def tearDown(self): - # Stop docker registry - self._stop_local_docker_registry() - - @classmethod - def _start_local_docker_registry(cls): - # https://docs.docker.com/registry/deploying/#run-a-local-registrys - start_cmd = [ - 'docker', 'run', '-d', '-p', '{}:{}'.format(DOCKER_REGISTRY_PORT, DOCKER_REGISTRY_PORT), - '--name', DOCKER_REGISTRY_NAME, 'registry:2' - ] - subprocess.check_call(start_cmd) - - @classmethod - def _stop_local_docker_registry(cls): - # https://docs.docker.com/registry/deploying/#run-a-local-registry - stop_cmd = ['docker', 'container', 'stop', DOCKER_REGISTRY_NAME] - subprocess.check_call(stop_cmd) - - clean_cmd = ['docker', 'container', 'rm', '-v', DOCKER_REGISTRY_NAME] - subprocess.check_call(clean_cmd) - - def test_full_cache(self): - """ - Test whether it's possible to restore cache entirely - :return: - """ - dockerfile_content = """ - FROM busybox - RUN touch ~/file1 - RUN touch ~/file2 - RUN touch ~/file3 - RUN touch ~/file4 - """ - platform = 'test_full_cache' - docker_tag = build_util.get_docker_tag(platform=platform, registry=DOCKER_REGISTRY_PATH) - dockerfile_path = os.path.join(DOCKERFILE_DIR, 'Dockerfile.build.' + platform) - try: - with open(dockerfile_path, 'w') as dockerfile_handle: - dockerfile_handle.write(dockerfile_content) - - # Warm up - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - def warm_up_lambda_func(): - build_util.build_docker( - docker_binary='docker', - platform=platform, - registry=DOCKER_REGISTRY_PATH, - num_retries=3, - no_cache=False - ) - _assert_docker_build(lambda_func=warm_up_lambda_func, expected_cache_hit_count=0, - expected_cache_miss_count=4) - - # Assert local cache is properly primed - def primed_cache_lambda_func(): - build_util.build_docker( - docker_binary='docker', - platform=platform, - registry=DOCKER_REGISTRY_PATH, - num_retries=3, - no_cache=False - ) - _assert_docker_build(lambda_func=primed_cache_lambda_func, expected_cache_hit_count=4, - expected_cache_miss_count=0) - - # Upload and clean local cache - docker_cache.build_save_containers(platforms=[platform], registry=DOCKER_REGISTRY_PATH, load_cache=False) - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - # Build with clean local cache and cache loading enabled - def clean_cache_lambda_func(): - docker_cache.build_save_containers( - platforms=[platform], registry=DOCKER_REGISTRY_PATH, load_cache=True) - _assert_docker_build(lambda_func=clean_cache_lambda_func, expected_cache_hit_count=4, - expected_cache_miss_count=0) - finally: - # Delete dockerfile - os.remove(dockerfile_path) - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - def test_partial_cache(self): - """ - Test whether it's possible to restore cache and then pit it up partially by using a Dockerfile which shares - some parts - :return: - """ - # These two dockerfiles diverge at the fourth RUN statement. Their common parts (1-3) should be re-used - dockerfile_content_1 = """ - FROM busybox - RUN touch ~/file1 - RUN touch ~/file2 - RUN touch ~/file3 - RUN touch ~/file4 - """ - dockerfile_content_2 = """ - FROM busybox - RUN touch ~/file1 - RUN touch ~/file2 - RUN touch ~/file3 - RUN touch ~/file5 - RUN touch ~/file4 - RUN touch ~/file6 - """ - platform = 'test_partial_cache' - docker_tag = build_util.get_docker_tag(platform=platform, registry=DOCKER_REGISTRY_PATH) - dockerfile_path = os.path.join(DOCKERFILE_DIR, 'Dockerfile.build.' + platform) - try: - # Write initial Dockerfile - with open(dockerfile_path, 'w') as dockerfile_handle: - dockerfile_handle.write(dockerfile_content_1) - - # Warm up - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - def warm_up_lambda_func(): - build_util.build_docker( - docker_binary='docker', - platform=platform, - registry=DOCKER_REGISTRY_PATH, - num_retries=3, - no_cache=False - ) - _assert_docker_build(lambda_func=warm_up_lambda_func, expected_cache_hit_count=0, - expected_cache_miss_count=4) - - # Assert local cache is properly primed - def primed_cache_lambda_func(): - build_util.build_docker( - docker_binary='docker', - platform=platform, - registry=DOCKER_REGISTRY_PATH, - num_retries=3, - no_cache=False - ) - _assert_docker_build(lambda_func=primed_cache_lambda_func, expected_cache_hit_count=4, - expected_cache_miss_count=0) - - # Upload and clean local cache - docker_cache.build_save_containers(platforms=[platform], registry=DOCKER_REGISTRY_PATH, load_cache=False) - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - # Replace Dockerfile with the second one, resulting in a partial cache hit - with open(dockerfile_path, 'w') as dockerfile_handle: - dockerfile_handle.write(dockerfile_content_2) - - # Test if partial cache is properly hit. It will attempt to load the cache from the first Dockerfile, - # resulting in a partial hit - def partial_cache_lambda_func(): - docker_cache.build_save_containers( - platforms=[platform], registry=DOCKER_REGISTRY_PATH, load_cache=True) - _assert_docker_build(lambda_func=partial_cache_lambda_func, expected_cache_hit_count=3, - expected_cache_miss_count=3) - - finally: - # Delete dockerfile - os.remove(dockerfile_path) - docker_cache.delete_local_docker_cache(docker_tag=docker_tag) - - -def _assert_docker_build(lambda_func, expected_cache_hit_count: int, expected_cache_miss_count: int): - with RedirectSubprocessOutput() as redirected_output: - lambda_func() - output = redirected_output.get_output() - assert output.count('Running in') == expected_cache_miss_count, \ - 'Expected {} "Running in", got {}. Log:{}'.\ - format(expected_cache_miss_count, output.count('Running in'), output) - assert output.count('Using cache') == expected_cache_hit_count, \ - 'Expected {} "Using cache", got {}. Log:{}'.\ - format(expected_cache_hit_count, output.count('Using cache'), output) diff --git a/ci/windows/test_jl07_cpu.ps1 b/ci/windows/test_jl07_cpu.ps1 deleted file mode 100644 index 4924957ddb68..000000000000 --- a/ci/windows/test_jl07_cpu.ps1 +++ /dev/null @@ -1,56 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -7z x -y windows_package.7z - -# set default output encoding to utf8 -$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8' - -$env:MXNET_HOME = [System.IO.Path]::GetFullPath('.\windows_package') -$env:JULIA_URL = "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7.0-win64.exe" -$env:JULIA_DEPOT_PATH = [System.IO.Path]::GetFullPath('.\julia-depot') - -$JULIA_DIR = [System.IO.Path]::GetFullPath('.\julia07') -$JULIA = "$JULIA_DIR\bin\julia" - -# Download most recent Julia Windows binary -[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -(New-Object System.Net.WebClient).DownloadFile($env:JULIA_URL, "julia-binary.exe") -if ($LastExitCode -ne 0) { Throw ("Error on downloading Julia Windows binary") } - -# Run installer silently, output to C:\julia07\julia -Start-Process -Wait "julia-binary.exe" -ArgumentList "/S /D=$JULIA_DIR" -if ($LastExitCode -ne 0) { Throw ("Error on installing Julia") } - -& $JULIA -e "using InteractiveUtils; versioninfo()" - -dir - -$src=' - using Pkg - Pkg.activate(".\\julia") - Pkg.build() - Pkg.test() -' - -$src > .\ci-build.jl - -# Redirect all stderr output to stdout, -# since Julia loggers output stuffs to stderr. -# Then, stderr triggers powershell NativeCommandError. -& $JULIA .\ci-build.jl 2>&1 | %{ "$_" } -if ($LastExitCode -eq 1) { Throw ("Error") } diff --git a/ci/windows/test_jl10_cpu.ps1 b/ci/windows/test_jl10_cpu.ps1 deleted file mode 100644 index b54b11a8a8ab..000000000000 --- a/ci/windows/test_jl10_cpu.ps1 +++ /dev/null @@ -1,56 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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. - -7z x -y windows_package.7z - -# set default output encoding to utf8 -$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8' - -$env:MXNET_HOME = [System.IO.Path]::GetFullPath('.\windows_package') -$env:JULIA_URL = "https://julialang-s3.julialang.org/bin/winnt/x64/1.0/julia-1.0.3-win64.exe" -$env:JULIA_DEPOT_PATH = [System.IO.Path]::GetFullPath('.\julia-depot') - -$JULIA_DIR = [System.IO.Path]::GetFullPath('.\julia10') -$JULIA = "$JULIA_DIR\bin\julia" - -# Download most recent Julia Windows binary -[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -(New-Object System.Net.WebClient).DownloadFile($env:JULIA_URL, "julia-binary.exe") -if ($LastExitCode -ne 0) { Throw ("Error on downloading Julia Windows binary") } - -# Run installer silently, output to C:\julia10\julia -Start-Process -Wait "julia-binary.exe" -ArgumentList "/S /D=$JULIA_DIR" -if ($LastExitCode -ne 0) { Throw ("Error on installing Julia") } - -& $JULIA -e "using InteractiveUtils; versioninfo()" - -dir - -$src=' - using Pkg - Pkg.activate(".\\julia") - Pkg.build() - Pkg.test() -' - -$src > .\ci-build.jl - -# Redirect all stderr output to stdout, -# since Julia loggers output stuffs to stderr. -# Then, stderr triggers powershell NativeCommandError. -& $JULIA .\ci-build.jl 2>&1 | %{ "$_" } -if ($LastExitCode -eq 1) { Throw ("Error") } diff --git a/config/distribution/darwin_cpu.cmake b/config/distribution/darwin_cpu.cmake index 790e18320157..ed295efd33d2 100644 --- a/config/distribution/darwin_cpu.cmake +++ b/config/distribution/darwin_cpu.cmake @@ -31,3 +31,4 @@ set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.") set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support") set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support") set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo") +set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support") diff --git a/config/distribution/linux_cpu.cmake b/config/distribution/linux_cpu.cmake index 15b4f5aa7e59..4579b42fce5c 100644 --- a/config/distribution/linux_cpu.cmake +++ b/config/distribution/linux_cpu.cmake @@ -29,3 +29,4 @@ set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.") set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support") set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support") set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo") +set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support") diff --git a/config/distribution/linux_cu100.cmake b/config/distribution/linux_cu100.cmake index 457a14f89a32..357ccd457593 100644 --- a/config/distribution/linux_cu100.cmake +++ b/config/distribution/linux_cu100.cmake @@ -31,6 +31,7 @@ set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.") set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support") set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support") set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo") +set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support") set(CUDACXX "/usr/local/cuda-10.0/bin/nvcc" CACHE STRING "Cuda compiler") set(MXNET_CUDA_ARCH "3.0;5.0;6.0;7.0" CACHE STRING "Cuda architectures") diff --git a/config/distribution/linux_cu101.cmake b/config/distribution/linux_cu101.cmake index 61089200f31f..29fdda2d6f0a 100644 --- a/config/distribution/linux_cu101.cmake +++ b/config/distribution/linux_cu101.cmake @@ -33,6 +33,7 @@ set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.") set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support") set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support") set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo") +set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support") set(CUDACXX "/usr/local/cuda-10.1/bin/nvcc" CACHE STRING "Cuda compiler") set(MXNET_CUDA_ARCH "3.0;5.0;6.0;7.0" CACHE STRING "Cuda architectures") diff --git a/config/distribution/linux_cu102.cmake b/config/distribution/linux_cu102.cmake index 9701b99a6a1f..4e7e0509e4f9 100644 --- a/config/distribution/linux_cu102.cmake +++ b/config/distribution/linux_cu102.cmake @@ -31,6 +31,7 @@ set(USE_TVM_OP OFF CACHE BOOL "Enable use of TVM operator build system.") set(USE_SSE ON CACHE BOOL "Build with x86 SSE instruction support") set(USE_F16C OFF CACHE BOOL "Build with x86 F16C instruction support") set(USE_LIBJPEG_TURBO ON CACHE BOOL "Build with libjpeg-turbo") +set(USE_DIST_KVSTORE ON CACHE BOOL "Build with DIST_KVSTORE support") set(CUDACXX "/usr/local/cuda-10.2/bin/nvcc" CACHE STRING "Cuda compiler") set(MXNET_CUDA_ARCH "3.0;5.0;6.0;7.0" CACHE STRING "Cuda architectures") diff --git a/docs/python_docs/_static/mxnet.css b/docs/python_docs/_static/mxnet.css index 7d4f7f115424..5c04804578c1 100644 --- a/docs/python_docs/_static/mxnet.css +++ b/docs/python_docs/_static/mxnet.css @@ -19,10 +19,6 @@ visibility: hidden; } -.document .page-content { - padding: 0 10% !important; -} - .mdl-layout__header--waterfall.is-casting-shadow { box-shadow: none !important; } diff --git a/docs/python_docs/python/api/gluon/index.rst b/docs/python_docs/python/api/gluon/index.rst index abb9072bfbd9..8a8b42549ce8 100644 --- a/docs/python_docs/python/api/gluon/index.rst +++ b/docs/python_docs/python/api/gluon/index.rst @@ -96,6 +96,12 @@ Training Loss functions for training neural networks. + .. card:: + :title: gluon.metric + :link: metric/index.html + + Metrics to evaluate the performance of a learned model. + .. card:: :title: gluon.Parameter :link: parameter.html @@ -155,4 +161,4 @@ Utilities parameter parameter_dict trainer - */index \ No newline at end of file + */index diff --git a/docs/python_docs/python/api/metric/index.rst b/docs/python_docs/python/api/gluon/metric/index.rst similarity index 94% rename from docs/python_docs/python/api/metric/index.rst rename to docs/python_docs/python/api/gluon/metric/index.rst index 4b24d1e703db..8c535973035d 100644 --- a/docs/python_docs/python/api/metric/index.rst +++ b/docs/python_docs/python/api/gluon/metric/index.rst @@ -15,9 +15,9 @@ specific language governing permissions and limitations under the License. -mxnet.metric +gluon.metric ============ -.. automodule:: mxnet.metric +.. automodule:: mxnet.gluon.metric :members: :autosummary: diff --git a/docs/python_docs/python/api/index.rst b/docs/python_docs/python/api/index.rst index 47363cf07c5c..0fd831d431c3 100644 --- a/docs/python_docs/python/api/index.rst +++ b/docs/python_docs/python/api/index.rst @@ -73,12 +73,6 @@ Gluon related modules Scheduling the learning rate. - .. card:: - :title: mxnet.metric - :link: metric/index.html - - Metrics to evaluate the performance of a learned model. - .. card:: :title: mxnet.kvstore :link: kvstore/index.html @@ -188,13 +182,6 @@ Advanced modules Engine properties management. - .. card:: - :title: mxnet.executor_manager - :link: mxnet/executor_manager/index.html - - Executor manager - - .. card:: :title: mxnet.rtc :link: mxnet/rtc/index.html diff --git a/docs/python_docs/python/api/mxnet/index.rst b/docs/python_docs/python/api/mxnet/index.rst index 96f20e683818..def5e276c110 100644 --- a/docs/python_docs/python/api/mxnet/index.rst +++ b/docs/python_docs/python/api/mxnet/index.rst @@ -32,7 +32,6 @@ mxnet mxnet.contrib mxnet.engine mxnet.executor - mxnet.executor_manager mxnet.gluon mxnet.image mxnet.initializer diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/1-ndarray.md b/docs/python_docs/python/tutorials/getting-started/crash-course/1-ndarray.md index d825eccab944..52835b4451f3 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/1-ndarray.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/1-ndarray.md @@ -15,107 +15,97 @@ -# Manipulate data with `ndarray` +# Step 1: Manipulate data with NP on MXNet -We'll start by introducing the `NDArray`, MXNet’s primary tool for storing and transforming data. If you’ve worked with `NumPy` before, you’ll notice that an NDArray is, by design, similar to NumPy’s multi-dimensional array. +This getting started exercise introduces the `np` package, which is similar to Numpy. For more information, please see [Differences between NP on MXNet and NumPy](/api/python/docs/tutorials/getting-started/np/np-vs-numpy.html). -## Get started +## Import packages and create an array -To get started, let's import the `ndarray` package (`nd` is a shorter alias) from MXNet. -```{.python .input n=1} -# If you haven't installed MXNet yet, you can uncomment the following line to -# install the latest stable release -# !pip install -U mxnet +To get started, run the following commands to import the `np` package together with the NumPy extensions package `npx`. Together, `np` with `npx` make up the NP on MXNet front end. -from mxnet import nd +```{.python .input n=1} +from mxnet import np, npx +npx.set_np() # Activate NumPy-like mode. ``` -Next, let's see how to create a 2D array (also called a matrix) with values from two sets of numbers: 1, 2, 3 and 4, 5, 6. This might also be referred to as a tuple of a tuple of integers. +In this step, create a 2D array (also called a matrix). The following code example creates a matrix with values from two sets of numbers: 1, 2, 3 and 4, 5, 6. This might also be referred to as a tuple of a tuple of integers. ```{.python .input n=2} -nd.array(((1,2,3),(5,6,7))) +np.array(((1,2,3),(5,6,7))) ``` -We can also create a very simple matrix with the same shape (2 rows by 3 columns), but fill it with 1s. +You can also create a very simple matrix with the same shape (2 rows by 3 columns), but fill it with 1s. ```{.python .input n=3} -x = nd.ones((2,3)) +x = np.ones((2,3)) x ``` -Often we’ll want to create arrays whose values are sampled randomly. For example, sampling values uniformly between -1 and 1. Here we create the same shape, but with random sampling. +You can create arrays whose values are sampled randomly. For example, sampling values uniformly between -1 and 1. The following code example creates the same shape, but with random sampling. ```{.python .input n=15} -y = nd.random.uniform(-1,1,(2,3)) +y = np.random.uniform(-1,1, (2,3)) y ``` -You can also fill an array of a given shape with a given value, such as `2.0`. - - -```{.python .input n=16} -x = nd.full((2,3), 2.0) -x -``` - -As with NumPy, the dimensions of each NDArray are accessible by accessing the `.shape` attribute. We can also query its `size`, which is equal to the product of the components of the shape. In addition, `.dtype` tells the data type of the stored values. +As with NumPy, the dimensions of each ndarray are shown by accessing the `.shape` attribute. As the following code example shows, you can also query for `size`, which is equal to the product of the components of the shape. In addition, `.dtype` tells the data type of the stored values. ```{.python .input n=17} (x.shape, x.size, x.dtype) ``` -## Operations +## Performing operations on an array -NDArray supports a large number of standard mathematical operations, such as element-wise multiplication: +An ndarray supports a large number of standard mathematical operations. Here are three examples. You can perform element-wise multiplication by using the following code example. ```{.python .input n=18} x * y ``` -Exponentiation: +You can perform exponentiation by using the following code example. ```{.python .input n=23} -y.exp() +np.exp(y) ``` -And transposing a matrix to compute a proper matrix-matrix product: +You can also find a matrix’s transpose to compute a proper matrix-matrix product by using the following code example. ```{.python .input n=24} -nd.dot(x, y.T) +np.dot(x, y.T) ``` -## Indexing +## Indexing an array -MXNet NDArrays support slicing in all the ridiculous ways you might imagine accessing your data. Here’s an example of reading a particular element, which returns a 1D array with shape `(1,)`. +The ndarrays support slicing in many ways you might want to access your data. The following code example shows how to read a particular element, which returns a 1D array with shape `(1,)`. ```{.python .input n=25} y[1,2] ``` -Read the second and third columns from `y`. +This example shows how to read the second and third columns from `y`. ```{.python .input n=26} y[:,1:3] ``` -and write to a specific element. +This example shows how to write to a specific element. ```{.python .input n=27} y[:,1:3] = 2 y ``` -Multi-dimensional slicing is also supported. +You can perform multi-dimensional slicing, which is shown in the following code example. ```{.python .input n=28} y[1:2,0:2] = 4 y ``` -## Converting between MXNet NDArray and NumPy +## Converting between MXNet ndarrays and NumPy ndarrays -Converting MXNet NDArrays to and from NumPy is easy. The converted arrays do not share memory. +You can convert MXNet ndarrays to and from NumPy ndarrays, as shown in the following example. The converted arrays do not share memory. ```{.python .input n=29} a = x.asnumpy() @@ -123,5 +113,9 @@ a = x.asnumpy() ``` ```{.python .input n=30} -nd.array(a) +np.array(a) ``` + +## Next steps + +Learn how to construct a neural network with the Gluon module: [Step 2: Create a neural network](2-nn.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/2-nn.md b/docs/python_docs/python/tutorials/getting-started/crash-course/2-nn.md index 88bb030ea502..f2ea348d636a 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/2-nn.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/2-nn.md @@ -15,18 +15,21 @@ -# Create a neural network +# Step 2: Create a neural network -Now let's look how to create neural networks in Gluon. In addition the NDArray package (`nd`) that we just covered, we now will also import the neural network `nn` package from `gluon`. +In this step, you learn how to use NP on MXNet to create neural networks in Gluon. In addition to the `np` package that you learned about in the previous step [Step 1: Manipulate data with NP on MXNet](1-ndarray.md), you also import the neural network `nn` package from `gluon`. + +Use the following commands to import the packages required for this step. ```{.python .input n=2} -from mxnet import nd +from mxnet import np, npx from mxnet.gluon import nn +npx.set_np() # Change MXNet to the numpy-like mode. ``` ## Create your neural network's first layer -Let's start with a dense layer with 2 output units. +Use the following code example to start with a dense layer with two output units. ```{.python .input n=31} @@ -34,20 +37,20 @@ layer = nn.Dense(2) layer ``` -Then initialize its weights with the default initialization method, which draws random values uniformly from $[-0.7, 0.7]$. +Initialize its weights with the default initialization method, which draws random values uniformly from $[-0.7, 0.7]$. You can see this in the following example. ```{.python .input n=32} layer.initialize() ``` -Then we do a forward pass with random data. We create a $(3,4)$ shape random input `x` and feed into the layer to compute the output. +Do a forward pass with random data, shown in the following example. We create a $(3,4)$ shape random input `x` and feed into the layer to compute the output. ```{.python .input n=34} -x = nd.random.uniform(-1,1,(3,4)) +x = np.random.uniform(-1,1,(3,4)) layer(x) ``` -As can be seen, the layer's input limit of 2 produced a $(3,2)$ shape output from our $(3,4)$ input. Note that we didn't specify the input size of `layer` before (though we can specify it with the argument `in_units=4` here), the system will automatically infer it during the first time we feed in data, create and initialize the weights. So we can access the weight after the first forward pass: +As can be seen, the layer's input limit of two produced a $(3,2)$ shape output from our $(3,4)$ input. You didn't specify the input size of `layer` before, though you can specify it with the argument `in_units=4` here. The system automatically infers it during the first time you feed in data, create, and initialize the weights. You can access the weight after the first forward pass, as shown in this example. ```{.python .input n=35} layer.weight.data() @@ -55,7 +58,7 @@ layer.weight.data() ## Chain layers into a neural network -Let's first consider a simple case that a neural network is a chain of layers. During the forward pass, we run layers sequentially one-by-one. The following code implements a famous network called [LeNet](http://yann.lecun.com/exdb/lenet/) through `nn.Sequential`. +Consider a simple case where a neural network is a chain of layers. During the forward pass, you run layers sequentially one-by-one. Use the following code to implement a famous network called [LeNet](http://yann.lecun.com/exdb/lenet/) through `nn.Sequential`. ```{.python .input} net = nn.Sequential() @@ -80,18 +83,18 @@ net -The usage of `nn.Sequential` is similar to `nn.Dense`. In fact, both of them are subclasses of `nn.Block`. The following codes show how to initialize the weights and run the forward pass. +Using `nn.Sequential` is similar to `nn.Dense`. In fact, both of them are subclasses of `nn.Block`. Use the following code to initialize the weights and run the forward pass. ```{.python .input} net.initialize() # Input shape is (batch_size, color_channels, height, width) -x = nd.random.uniform(shape=(4,1,28,28)) +x = np.random.uniform(size=(4,1,28,28)) y = net(x) y.shape ``` -We can use `[]` to index a particular layer. For example, the following -accesses the 1st layer's weight and 6th layer's bias. +You can use `[]` to index a particular layer. For example, the following +accesses the first layer's weight and sixth layer's bias. ```{.python .input} (net[0].weight.data().shape, net[5].bias.data().shape) @@ -100,9 +103,9 @@ accesses the 1st layer's weight and 6th layer's bias. ## Create a neural network flexibly In `nn.Sequential`, MXNet will automatically construct the forward function that sequentially executes added layers. -Now let's introduce another way to construct a network with a flexible forward function. +Here is another way to construct a network with a flexible forward function. -To do it, we create a subclass of `nn.Block` and implement two methods: +Create a subclass of `nn.Block` and implement two methods by using the following code. - `__init__` create the layers - `forward` define the forward function. @@ -117,7 +120,7 @@ class MixMLP(nn.Block): nn.Dense(4, activation='relu')) self.dense = nn.Dense(5) def forward(self, x): - y = nd.relu(self.blk(x)) + y = npx.relu(self.blk(x)) print(y) return self.dense(y) @@ -125,18 +128,23 @@ net = MixMLP() net ``` -In the sequential chaining approach, we can only add instances with `nn.Block` as the base class and then run them in a forward pass. In this example, we used `print` to get the intermediate results and `nd.relu` to apply relu activation. So this approach provides a more flexible way to define the forward function. +In the sequential chaining approach, you can only add instances with `nn.Block` as the base class and then run them in a forward pass. In this example, you used `print` to get the intermediate results and `nd.relu` to apply relu activation. This approach provides a more flexible way to define the forward function. -The usage of `net` is similar as before. +The following code example uses `net` in a similar manner as earlier. ```{.python .input} net.initialize() -x = nd.random.uniform(shape=(2,2)) +x = np.random.uniform(size=(2,2)) net(x) ``` -Finally, let's access a particular layer's weight +Finally, access a particular layer's weight with this code. ```{.python .input n=8} net.blk[1].weight.data() ``` + +## Next steps + +After you create a neural network, learn how to automatically +compute the gradients in [Step 3: Automatic differentiation with autograd](3-autograd.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/3-autograd.md b/docs/python_docs/python/tutorials/getting-started/crash-course/3-autograd.md index b7cb9f4dee8b..b959b4deb4a6 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/3-autograd.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/3-autograd.md @@ -15,49 +15,52 @@ -# Automatic differentiation with `autograd` +# Step 3: Automatic differentiation with autograd -We train models to get better and better as a function of experience. Usually, getting better means minimizing a loss function. To achieve this goal, we often iteratively compute the gradient of the loss with respect to weights and then update the weights accordingly. While the gradient calculations are straightforward through a chain rule, for complex models, working it out by hand can be a pain. +In this step, you learn how to use the MXNet `autograd` package to perform gradient calculations by automatically calculating derivatives. -Before diving deep into the model training, let's go through how MXNet’s `autograd` package expedites this work by automatically calculating derivatives. +This is helpful because it will help you save time and effort. You train models to get better as a function of experience. Usually, getting better means minimizing a loss function. To achieve this goal, you often iteratively compute the gradient of the loss with respect to weights and then update the weights accordingly. Gradient calculations are straightforward through a chain rule. However, for complex models, working this out manually is challenging. -## Basic usage +The `autograd` package helps you by automatically calculating derivatives. -Let's first import the `autograd` package. +## Basic use + +To get started, import the `autograd` package as in the following code. ```{.python .input} -from mxnet import nd +from mxnet import np, npx from mxnet import autograd +npx.set_np() ``` -As a toy example, let’s say that we are interested in differentiating a function $f(x) = 2 x^2$ with respect to parameter $x$. We can start by assigning an initial value of $x$. +As an example, you could differentiate a function $f(x) = 2 x^2$ with respect to parameter $x$. You can start by assigning an initial value of $x$, as follows: ```{.python .input n=3} -x = nd.array([[1, 2], [3, 4]]) +x = np.array([[1, 2], [3, 4]]) x ``` -Once we compute the gradient of $f(x)$ with respect to $x$, we’ll need a place to store it. In MXNet, we can tell an NDArray that we plan to store a gradient by invoking its `attach_grad` method. +After you compute the gradient of $f(x)$ with respect to $x$, you need a place to store it. In MXNet, you can tell an ndarray that you plan to store a gradient by invoking its `attach_grad` method, shown in the following example. ```{.python .input n=6} x.attach_grad() ``` -Now we’re going to define the function $y=f(x)$. To let MXNet store $y$, so that we can compute gradients later, we need to put the definition inside a `autograd.record()` scope. +Next, define the function $y=f(x)$. To let MXNet store $y$, so that you can compute gradients later, use the following code to put the definition inside an `autograd.record()` scope. ```{.python .input n=7} with autograd.record(): y = 2 * x * x ``` -Let’s invoke back propagation (backprop) by calling `y.backward()`. When $y$ has more than one entry, `y.backward()` is equivalent to `y.sum().backward()`. +You can invoke back propagation (backprop) by calling `y.backward()`. When $y$ has more than one entry, `y.backward()` is equivalent to `y.sum().backward()`. ```{.python .input n=8} y.backward() ``` -Now, let’s see if this is the expected output. Note that $y=2x^2$ and $\frac{dy}{dx} = 4x$, which should be `[[4, 8],[12, 16]]`. Let's check the automatically computed results: +Next, verify whether this is the expected output. Note that $y=2x^2$ and $\frac{dy}{dx} = 4x$, which should be `[[4, 8],[12, 16]]`. Check the automatically computed results. ```{.python .input n=9} x.grad @@ -65,35 +68,39 @@ x.grad ## Using Python control flows -Sometimes we want to write dynamic programs where the execution depends on some real-time values. MXNet will record the execution trace and compute the gradient as well. +Sometimes you want to write dynamic programs where the execution depends on real-time values. MXNet records the execution trace and computes the gradient as well. -Consider the following function `f`: it doubles the inputs until it's `norm` reaches 1000. Then it selects one element depending on the sum of its elements. +Consider the following function `f` in the following example code. The function doubles the inputs until its `norm` reaches 1000. Then it selects one element depending on the sum of its elements. ```{.python .input} def f(a): b = a * 2 - while b.norm().asscalar() < 1000: + while np.abs(b).sum() < 1000: b = b * 2 - if b.sum().asscalar() >= 0: + if b.sum() >= 0: c = b[0] else: c = b[1] return c ``` -We record the trace and feed in a random value: +In this example, you record the trace and feed in a random value. ```{.python .input} -a = nd.random.uniform(shape=2) +a = np.random.uniform(size=2) a.attach_grad() with autograd.record(): c = f(a) c.backward() ``` -We know that `b` is a linear function of `a`, and `c` is chosen from `b`. Then the gradient with respect to `a` be will be either `[c/a[0], 0]` or `[0, c/a[1]]`, depending on which element from `b` we picked. Let's find the results: +You can see that `b` is a linear function of `a`, and `c` is chosen from `b`. The gradient with respect to `a` be will be either `[c/a[0], 0]` or `[0, c/a[1]]`, depending on which element from `b` is picked. You see the results of this example with this code: ```{.python .input} -[a.grad, c/a] +a.grad == c/a ``` + +## Next Steps + +After you have used `autograd`, learn about training a neural network. See [Step 4: Train the neural network](4-train.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/4-train.md b/docs/python_docs/python/tutorials/getting-started/crash-course/4-train.md index 3a7f0d090bdf..ec3a07e52057 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/4-train.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/4-train.md @@ -15,37 +15,37 @@ -# Train the neural network +# Step 4: Train the neural network -In this section, we will discuss how to train the previously defined network with data. We first import the libraries. The new ones are `mxnet.init` for more weight initialization methods, the `datasets` and `transforms` to load and transform computer vision datasets, `matplotlib` for drawing, and `time` for benchmarking. +In this step, you learn how to train the previously defined network with data. First, import the libraries. The new ones are `mxnet.init` for more weight initialization methods. Import the `datasets` and `transforms` to load and transform computer vision datasets. Import `matplotlib` for drawing, and `time` for benchmarking. The example command here shows this. ```{.python .input n=1} # Uncomment the following line if matplotlib is not installed. # !pip install matplotlib -from mxnet import nd, gluon, init, autograd +from mxnet import np, npx, gluon, init, autograd from mxnet.gluon import nn -from mxnet.gluon.data.vision import datasets, transforms from IPython import display import matplotlib.pyplot as plt import time +npx.set_np() ``` ## Get data -The handwritten digit MNIST dataset is one of the most commonly used datasets in deep learning. But it is too simple to get a 99% accuracy. Here we use a similar but slightly more complicated dataset called FashionMNIST. The goal is no longer to classify numbers, but clothing types instead. +The handwritten digit, MNIST dataset is one of the most commonly used datasets in deep learning. However, it's too simple to get 99 percent accuracy. For this tutorial, you use a similar but slightly more complicated dataset called FashionMNIST. The end-goal is to classify clothing types. The dataset can be automatically downloaded through Gluon's `data.vision.datasets` module. The following code downloads the training dataset and shows the first example. ```{.python .input n=2} -mnist_train = datasets.FashionMNIST(train=True) +mnist_train = gluon.data.vision.datasets.FashionMNIST(train=True) X, y = mnist_train[0] ('X shape: ', X.shape, 'X dtype', X.dtype, 'y:', y) ``` -Each example in this dataset is a $28\times 28$ size grey image, which is presented as NDArray with the shape format of `(height, width, channel)`. The label is a `numpy` scalar. +Each example in this dataset is a $28\times 28$ size grey image, which is presented as ndarray with the shape format of `(height, width, channel)`. The label is a `numpy` scalar. -Next, we visualize the first ten examples. +Next, visualize the first six examples. ```{.python .input n=3} text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', @@ -54,7 +54,7 @@ X, y = mnist_train[0:10] # plot images display.set_matplotlib_formats('svg') _, figs = plt.subplots(1, X.shape[0], figsize=(15, 15)) -for f,x,yi in zip(figs, X,y): +for f, x, yi in zip(figs, X, y): # 3D->2D by removing the last channel dim f.imshow(x.reshape((28,28)).asnumpy()) ax = f.axes @@ -65,16 +65,16 @@ for f,x,yi in zip(figs, X,y): plt.show() ``` -In order to feed data into a Gluon model, we need to convert the images to the `(channel, height, width)` format with a floating point data type. It can be done by `transforms.ToTensor`. In addition, we normalize all pixel values with `transforms.Normalize` with the real mean 0.13 and standard deviation 0.31. We chain these two transforms together and apply it to the first element of the data pair, namely the images. +In order to feed data into a Gluon model, convert the images to the `(channel, height, width)` format with a floating point data type. It can be done by `transforms.ToTensor`. In addition, normalize all pixel values with `transforms.Normalize` with the real mean 0.13 and standard deviation 0.31. You can chain these two transforms together and apply it to the first element of the data pair, namely the images. ```{.python .input n=4} -transformer = transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize(0.13, 0.31)]) +transformer = gluon.data.vision.transforms.Compose([ + gluon.data.vision.transforms.ToTensor(), + gluon.data.vision.transforms.Normalize(0.13, 0.31)]) mnist_train = mnist_train.transform_first(transformer) ``` -`FashionMNIST` is a subclass of `gluon.data.Dataset`, which defines how to get the `i`-th example. In order to use it in training, we need to get a (randomized) batch of examples. It can be easily done by `gluon.data.DataLoader`. Here we use four works to process data in parallel, which is often necessary especially for complex data transforms. +`FashionMNIST` is a subclass of `gluon.data.Dataset`, which defines how to get the `i`-th example. In order to use it in training, you need to get a (randomized) batch of examples. Do this by using `gluon.data.DataLoader`. The example here uses four works to process data in parallel, which is often necessary especially for complex data transforms. ```{.python .input n=5} batch_size = 256 @@ -90,18 +90,18 @@ for data, label in train_data: break ``` -Finally, we create a validation dataset and data loader. +Finally, create a validation dataset and data loader. ```{.python .input n=7} mnist_valid = gluon.data.vision.FashionMNIST(train=False) valid_data = gluon.data.DataLoader( mnist_valid.transform_first(transformer), - batch_size=batch_size, num_workers=4) + batch_size=batch_size, num_workers=4) ``` ## Define the model -We reimplement the same LeNet introduced before. One difference here is that we changed the weight initialization method to `Xavier`, which is a popular choice for deep convolutional neural networks. +Implement the network called [LeNet](http://yann.lecun.com/exdb/lenet/). One difference here is that you change the weight initialization method to `Xavier`, which is a popular choice for deep convolutional neural networks. ```{.python .input n=8} net = nn.Sequential() @@ -109,40 +109,38 @@ net.add(nn.Conv2D(channels=6, kernel_size=5, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), nn.Conv2D(channels=16, kernel_size=3, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), - nn.Flatten(), nn.Dense(120, activation="relu"), nn.Dense(84, activation="relu"), nn.Dense(10)) net.initialize(init=init.Xavier()) ``` -Besides the neural network, we need to define the loss function and optimization method for training. We will use standard softmax cross entropy loss for classification problems. It first performs softmax on the output to obtain the predicted probability, and then compares the label with the cross entropy. +In addition to the neural network, define the loss function and optimization method for training. Use standard softmax cross entropy loss for classification problems. It first performs softmax on the output to obtain the predicted probability, and then compares the label with the cross entropy. ```{.python .input n=9} softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss() ``` -The optimization method we pick is the standard stochastic gradient descent with constant learning rate of 0.1. +The optimization method you pick is the standard stochastic gradient descent with constant learning rate of 0.1. ```{.python .input n=10} trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1}) ``` -The `trainer` is created with all parameters (both weights and gradients) in `net`. Later on, we only need to call the `step` method to update its weights. +The `trainer` is created with all parameters (both weights and gradients) in `net`. Later on, you only need to call the `step` method to update its weights. -## Train +## Train the model -We create an auxiliary function to calculate the model accuracy. +Create an auxiliary function to calculate the model accuracy. ```{.python .input n=11} def acc(output, label): # output: (batch, num_output) float32 ndarray # label: (batch, ) int32 ndarray - return (output.argmax(axis=1) == - label.astype('float32')).mean().asscalar() + return (output.argmax(axis=1) == label.astype('float32')).mean() ``` -Now we can implement the complete training loop. +Implement the complete training loop. ```{.python .input n=12} for epoch in range(10): @@ -157,7 +155,7 @@ for epoch in range(10): # update parameters trainer.step(batch_size) # calculate training metrics - train_loss += loss.mean().asscalar() + train_loss += loss.mean() train_acc += acc(output, label) # calculate validation accuracy for data, label in valid_data: @@ -169,8 +167,12 @@ for epoch in range(10): ## Save the model -Finally, we save the trained parameters onto disk, so that we can use them later. +Finally, save the trained parameters onto disk, so that you can use them later. ```{.python .input n=13} net.save_parameters('net.params') ``` + +## Next Steps + +After the model is trained and saved, learn how to use it to predict new examples: [Step 5: Predict with a pretrained model](5-predict.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/5-predict.md b/docs/python_docs/python/tutorials/getting-started/crash-course/5-predict.md index 5141ae39acb4..a0b948a8d67c 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/5-predict.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/5-predict.md @@ -15,24 +15,23 @@ -# Predict with a pre-trained model +# Step 5: Predict with a pretrained model -A saved model can be used in multiple places, such as to continue training, to fine tune the model, and for prediction. In this tutorial we will discuss how to predict new examples using a pretrained model. +In this step, you learn how to predict new examples using a pretrained model. A saved model can be used in multiple places, such as to continue training, to fine tune the model, and for prediction. ## Prerequisites -Please run the [previous tutorial](4-train.html) to train the network and save its parameters to file. You will need this file to run the following steps. +Before you begin the procedures here, run :label:`crash_course_train` to train the network and save its parameters to file. You use this file to run the following steps. ```{.python .input n=1} -from mxnet import nd -from mxnet import gluon +from mxnet import np, npx, gluon, image from mxnet.gluon import nn -from mxnet.gluon.data.vision import datasets, transforms from IPython import display import matplotlib.pyplot as plt +npx.set_np() ``` -To start, we will copy a simple model's definition. +To start, copy a simple model's definition by using the following code. ```{.python .input n=2} net = nn.Sequential() @@ -40,13 +39,12 @@ net.add(nn.Conv2D(channels=6, kernel_size=5, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), nn.Conv2D(channels=16, kernel_size=3, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), - nn.Flatten(), nn.Dense(120, activation="relu"), nn.Dense(84, activation="relu"), nn.Dense(10)) ``` -In the last section, we saved all parameters into a file, now let's load it back. +In the previous step, you saved all parameters to a file. Now load it back. ```{.python .input n=3} net.load_parameters('net.params') @@ -54,37 +52,37 @@ net.load_parameters('net.params') ## Predict -Remember the data transformation we did for training? Now we need the same transformation for predicting. +Remember the data transformation you did for the training step? The following code provides the same transformation for predicting. ```{.python .input n=4} -transformer = transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize(0.13, 0.31)]) +transformer = gluon.data.vision.transforms.Compose([ + gluon.data.vision.transforms.ToTensor(), + gluon.data.vision.transforms.Normalize(0.13, 0.31)]) ``` -Now let's try to predict the first ten images in the validation dataset and store the predictions into `preds`. +Use the following code to predict the first six images in the validation dataset and store the predictions into `preds`. ```{.python .input n=5} -mnist_valid = datasets.FashionMNIST(train=False) +mnist_valid = gluon.data.vision.datasets.FashionMNIST(train=False) X, y = mnist_valid[:10] preds = [] for x in X: - x = transformer(x).expand_dims(axis=0) + x = np.expand_dims(transformer(x), axis=0) pred = net(x).argmax(axis=1) - preds.append(pred.astype('int32').asscalar()) + preds.append(int(pred)) ``` -Finally, we visualize the images and compare the prediction with the ground truth. +Finally, use the following code to visualize the images and compare the prediction with the ground truth. ```{.python .input n=15} _, figs = plt.subplots(1, 10, figsize=(15, 15)) text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'] display.set_matplotlib_formats('svg') -for f,x,yi,pyi in zip(figs, X, y, preds): +for f, x, yi, pyi in zip(figs, X, y, preds): f.imshow(x.reshape((28,28)).asnumpy()) ax = f.axes - ax.set_title(text_labels[yi]+'\n'+text_labels[pyi]) + ax.set_title(text_labels[int(yi)]+'\n'+text_labels[pyi]) ax.title.set_fontsize(14) ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) @@ -94,39 +92,35 @@ plt.show() ## Predict with models from Gluon model zoo -The LeNet trained on FashionMNIST is a good example to start with, but too simple to predict real-life pictures. Instead of training large-scale model from scratch, [Gluon model zoo](https://mxnet.apache.org/api/python/gluon/model_zoo.html) provides multiple pre-trained powerful models. For example, we can download and load a pre-trained ResNet-50 V2 model that was trained on the ImageNet dataset. +The LeNet, trained on FashionMNIST, is a good example to start with. However, it's too simple to predict real-life pictures. In order to save the time and effort of training a large-scale model from scratch, the [Gluon model zoo](https://mxnet.incubator.apache.org/api/python/gluon/model_zoo.html) provides multiple pre-trained models. For example, with the following code example, you can download a pre-trained ResNet-50 V2 model that was trained on the ImageNet dataset. ```{.python .input n=7} -from mxnet.gluon.model_zoo import vision as models -from mxnet.gluon.utils import download -from mxnet import image - -net = models.resnet50_v2(pretrained=True) +net = gluon.model_zoo.vision.resnet50_v2(pretrained=True) ``` -We also download and load the text labels for each class. +You'll also need to download the text labels for each class, as in the following example. ```{.python .input n=8} url = 'http://data.mxnet.io/models/imagenet/synset.txt' -fname = download(url) +fname = gluon.utils.download(url) with open(fname, 'r') as f: text_labels = [' '.join(l.split()[1:]) for l in f] ``` -We randomly pick a dog image from Wikipedia as a test image, download and read it. +The following example shows how to select a dog image from Wikipedia as a test, download and read it. ```{.python .input n=9} url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/\ Golden_Retriever_medium-to-light-coat.jpg/\ 365px-Golden_Retriever_medium-to-light-coat.jpg' -fname = download(url) -x = image.imread(fname) +fname = gluon.utils.download(url) +x = image.imread(fname) # TODO, use npx.image instead ``` -Following the conventional way of preprocessing ImageNet data: +Following the conventional way of preprocessing ImageNet data, do the following: -1. Resize the short edge into 256 pixes, -2. And then perform a center crop to obtain a 224-by-224 image. +1. Resize the short edge into 256 pixes. +2. Perform a center crop to obtain a 224-by-224 image. ```{.python .input n=10} x = image.resize_short(x, 256) @@ -135,27 +129,31 @@ plt.imshow(x.asnumpy()) plt.show() ``` -Now you may know it is a golden retriever (You can also infer it from the image URL). +Now you can see it is a golden retriever. You can also infer it from the image URL. -The futher data transformation is similar to FashionMNIST except that we subtract the RGB means and divide by the corresponding variances to normalize each color channel. +The next data transformation is similar to FashionMNIST. Here, you subtract the RGB means and divide by the corresponding variances to normalize each color channel. ```{.python .input n=11} def transform(data): - data = data.transpose((2,0,1)).expand_dims(axis=0) - rgb_mean = nd.array([0.485, 0.456, 0.406]).reshape((1,3,1,1)) - rgb_std = nd.array([0.229, 0.224, 0.225]).reshape((1,3,1,1)) + data = np.expand_dims(np.transpose(data, (2,0,1)), axis=0) + rgb_mean = np.array([0.485, 0.456, 0.406]).reshape((1,3,1,1)) + rgb_std = np.array([0.229, 0.224, 0.225]).reshape((1,3,1,1)) return (data.astype('float32') / 255 - rgb_mean) / rgb_std ``` -Now we can recognize the object in the image now. We perform an additional softmax on the output to obtain probability scores. And then print the top-5 recognized objects. +Now you can recognize the object in the image. Perform an additional softmax on the output to obtain probability scores. Print the top-5 recognized objects. ```{.python .input n=12} -prob = net(transform(x)).softmax() -idx = prob.topk(k=5)[0] +prob = npx.softmax(net(transform(x))) +idx = npx.topk(prob, k=5)[0] for i in idx: - i = int(i.asscalar()) print('With prob = %.5f, it contains %s' % ( - prob[0,i].asscalar(), text_labels[i])) + prob[0, int(i)], text_labels[int(i)])) ``` -As can be seen, the model is fairly confident the image contains a golden retriever. +As can be seen, the model is fairly confident that the image contains a golden retriever. + +## Next Steps + +You might find that both training and prediction are a little bit slow. If you have a GPU +available, learn how to accomplish your tasks faster in [Step 6: Use GPUs to increase efficiency](6-use_gpus.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/6-use_gpus.md b/docs/python_docs/python/tutorials/getting-started/crash-course/6-use_gpus.md index fc457ea7dc33..6f9cc5d3c1d9 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/6-use_gpus.md +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/6-use_gpus.md @@ -15,60 +15,60 @@ -# Use GPUs +# Step 6: Use GPUs to increase efficiency -We often use GPUs to train and deploy neural networks, because it offers significant more computation power compared to CPUs. In this tutorial we will introduce how to use GPUs with MXNet. +In this step, you learn how to use graphics processing units (GPUs) with MXNet. If you use GPUs to train and deploy neural networks, you get significantly more computational power when compared to central processing units (CPUs). -First, make sure you have at least one Nvidia GPU in your machine and CUDA -properly installed. Other GPUs such as AMD and Intel GPUs are not supported -yet. Then be sure you have installed the GPU-enabled version of MXNet. +## Prerequisites -```{.python .input n=15} -# If you pip installed the plain `mxnet` before, uncomment the -# following two lines to install the GPU version. You may need to -# replace `cu92` according to your CUDA version. -# !pip uninstall mxnet -# !pip install mxnet-cu92 +Before you start the other steps here, make sure you have at least one Nvidia GPU in your machine and CUDA properly installed. GPUs from AMD and Intel are not supported. Install the GPU-enabled version of MXNet. -from mxnet import nd, gpu, gluon, autograd +Use the following commands to check the number GPUs that are available. + +```{.python .input n=2} +from mxnet import np, npx, gluon, autograd from mxnet.gluon import nn -from mxnet.gluon.data.vision import datasets, transforms import time +npx.set_np() + +npx.num_gpus() ``` ## Allocate data to a GPU -You may notice that MXNet's NDArray is very similar to Numpy. One major difference is NDArray has a `context` attribute that specifies which device this array is on. By default, it is `cpu()`. Now we will change it to the first GPU. You can use `gpu()` or `gpu(0)` to indicate the first GPU. +MXNet's ndarray is very similar to NumPy. One major difference is MXNet's ndarray has a `context` attribute that specifies which device an array is on. By default, it is on `npx.cpu()`. Change it to the first GPU with the following code. Use `npx.gpu()` or `npx.gpu(0)` to indicate the first GPU. ```{.python .input n=10} -x = nd.ones((3,4), ctx=gpu()) +gpu = npx.gpu() if npx.num_gpus() > 0 else npx.cpu() +x = np.ones((3,4), ctx=gpu) x ``` -For a CPU, MXNet will allocate data on main memory, and try to use all CPU cores as possible, even if there is more than one CPU socket. While if there are multiple GPUs, MXNet needs to specify which GPUs the NDArray will be allocated. +If you're using a CPU, MXNet allocates data on main memory and tries to use as many CPU cores as possible. This is true even if there is more than one CPU socket. If there are multiple GPUs, MXNet specifies which GPUs the ndarray is allocated. -Let's assume there is a least one more GPU. We can create another NDArray and assign it there. (If you only have one GPU, then you will see an error). Here we copy `x` to the second GPU, `gpu(1)`: +Assume there is a least one more GPU. Create another ndarray and assign it there. If you only have one GPU, then you get an error. In the example code here, you copy `x` to the second GPU, `npx.gpu(1)`: ```{.python .input n=11} -x.copyto(gpu(1)) +gpu_1 = npx.gpu(1) if npx.num_gpus() > 1 else npx.cpu() +x.copyto(gpu_1) ``` -MXNet needs users to explicitly move data between devices. But several operators such as `print`, `asnumpy` and `asscalar`, will implicitly move data to main memory. +MXNet requries that users explicitly move data between devices. But several operators such as `print`, and `asnumpy`, will implicitly move data to main memory. ## Run an operation on a GPU -To perform an operation on a particular GPU, we only need to guarantee that the inputs of this operation are already on that GPU. The output will be allocated on the same GPU as well. Almost all operators in the `nd` module support running on a GPU. +To perform an operation on a particular GPU, you only need to guarantee that the input of an operation is already on that GPU. The output is allocated on the same GPU as well. Almost all operators in the `np` and `npx` module support running on a GPU. ```{.python .input n=21} -y = nd.random.uniform(shape=(3,4), ctx=gpu()) +y = np.random.uniform(size=(3,4), ctx=gpu) x + y ``` -Remember that if the inputs are not on the same GPU, you will see an error. +Remember that if the inputs are not on the same GPU, you get an error. ## Run a neural network on a GPU -Similarly, to run a neural network on a GPU, we only need to copy/move the input data and parameters to the GPU. Let's reuse the previously defined LeNet. +To run a neural network on a GPU, you only need to copy and move the input data and parameters to the GPU. Reuse the previously defined LeNet. The following code example shows this. ```{.python .input n=16} net = nn.Sequential() @@ -76,51 +76,50 @@ net.add(nn.Conv2D(channels=6, kernel_size=5, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), nn.Conv2D(channels=16, kernel_size=3, activation='relu'), nn.MaxPool2D(pool_size=2, strides=2), - nn.Flatten(), nn.Dense(120, activation="relu"), nn.Dense(84, activation="relu"), nn.Dense(10)) ``` -And then load the saved parameters into GPU 0 directly, or use `net.reset_ctx` to change the device. +Load the saved parameters into GPU 0 directly as shown here, or use `net.collect_params().reset_ctx` to change the device. ```{.python .input n=20} -net.load_parameters('net.params', ctx=gpu(0)) +net.load_parameters('net.params', ctx=gpu) ``` -Now create input data on GPU 0. The forward function will then run on GPU 0. +Use the following command to create input data on GPU 0. The forward function will then run on GPU 0. ```{.python .input n=22} -x = nd.random.uniform(shape=(1,1,28,28), ctx=gpu(0)) -net(x) +# x = np.random.uniform(size=(1,1,28,28), ctx=gpu) +# net(x) FIXME ``` -## [Advanced] Multi-GPU training +## Training with multiple GPUs -Finally, we show how to use multiple GPUs to jointly train a neural network through data parallelism. Let's assume there are *n* GPUs. We split each data batch into *n* parts, and then each GPU will run the forward and backward passes using one part of the data. +Finally, you can see how to use multiple GPUs to jointly train a neural network through data parallelism. Assume there are *n* GPUs. Split each data batch into *n* parts, and then each GPU will run the forward and backward passes using one part of the data. -Let's first copy the data definitions and the transform function from the [previous tutorial](5-predict.html). +First copy the data definitions with the following commands, and the transform function from the [Predict tutorial](5-predict.md). ```{.python .input} batch_size = 256 -transformer = transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize(0.13, 0.31)]) +transformer = gluon.data.vision.transforms.Compose([ + gluon.data.vision.transforms.ToTensor(), + gluon.data.vision.transforms.Normalize(0.13, 0.31)]) train_data = gluon.data.DataLoader( - datasets.FashionMNIST(train=True).transform_first(transformer), - batch_size, shuffle=True, num_workers=4) + gluon.data.vision.datasets.FashionMNIST(train=True).transform_first( + transformer), batch_size, shuffle=True, num_workers=4) valid_data = gluon.data.DataLoader( - datasets.FashionMNIST(train=False).transform_first(transformer), - batch_size, shuffle=False, num_workers=4) + gluon.data.vision.datasets.FashionMNIST(train=False).transform_first( + transformer), batch_size, shuffle=False, num_workers=4) ``` -The training loop is quite similar to what we introduced before. The major differences are highlighted in the following code. +The training loop is quite similar to that shown earlier. The major differences are highlighted in the following code. ```{.python .input} # Diff 1: Use two GPUs for training. -devices = [gpu(0), gpu(1)] +devices = [gpu, gpu_1] # Diff 2: reinitialize the parameters and place them on multiple GPUs -net.initialize(force_reinit=True, ctx=devices) +net.collect_params().initialize(force_reinit=True, ctx=devices) # Loss and trainer are the same as before softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss() trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1}) @@ -139,8 +138,14 @@ for epoch in range(10): for l in losses: l.backward() trainer.step(batch_size) - # Diff 5: sum losses over all devices - train_loss += sum([l.sum().asscalar() for l in losses]) + # Diff 5: sum losses over all devices. Here float will copy data + # into CPU. + train_loss += sum([float(l.sum()) for l in losses]) print("Epoch %d: loss %.3f, in %.1f sec" % ( epoch, train_loss/len(train_data)/batch_size, time.time()-tic)) ``` + +## Next steps + +Now you have completed training and predicting with a neural network by using NP on MXNet and +Gluon. You can check the guides to these two front ends: [What is NP on MXNet](../np/index.html) and [gluon](../gluon_from_experiment_to_deployment.md). diff --git a/docs/python_docs/python/tutorials/getting-started/crash-course/index.rst b/docs/python_docs/python/tutorials/getting-started/crash-course/index.rst index 124c94ae0814..b9a86e0978c9 100644 --- a/docs/python_docs/python/tutorials/getting-started/crash-course/index.rst +++ b/docs/python_docs/python/tutorials/getting-started/crash-course/index.rst @@ -1,27 +1,8 @@ -.. Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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. - -Crash Course +Getting started with NP on MXNet ============ -This crash course will give you a quick overview of the core concept of NDArray -(manipulating multiple dimensional arrays) and Gluon (create and train neural -networks). This is a good place to start if you are already familiar with -machine learning or other deep learning frameworks. +This crash course shows how to get started with NP on MXNet. The topics here provide a quick overview of the core concepts for both NP on MXNet, which helps you manipulate multiple dimensional arrays, and Gluon, which helps you create and train neural +networks. This is a good place to start if you are already familiar with machine learning or other deep learning frameworks. .. toctree:: :maxdepth: 1 @@ -33,20 +14,3 @@ machine learning or other deep learning frameworks. 4-train 5-predict 6-use_gpus - - -.. - # add back the videos until apis are updated. - You can also watch the video tutorials for this crash course. Note that two APIs - described in vidoes have changes: - - - ``with name_scope`` is not necessary any more. - - use ``save_parameters/load_parameters`` instead of ``save_params/load_params`` - - .. raw:: html - - - - diff --git a/docs/python_docs/python/tutorials/getting-started/index.rst b/docs/python_docs/python/tutorials/getting-started/index.rst index 9402f14061d6..dce53ee01319 100644 --- a/docs/python_docs/python/tutorials/getting-started/index.rst +++ b/docs/python_docs/python/tutorials/getting-started/index.rst @@ -28,6 +28,12 @@ The following tutorials teach how to use MXNet. A quick overview of the core concepts of MXNet using the Gluon API. + .. card:: + :title: What is NP on MXNet + :link: np/index.html + + What is NP on MXNet + .. card:: :title: Moving from other frameworks :link: to-mxnet/index.html @@ -57,6 +63,7 @@ The following tutorials teach how to use MXNet. :maxdepth: 2 crash-course/index + np/index to-mxnet/index gluon_from_experiment_to_deployment logistic_regression_explained.md diff --git a/docs/python_docs/python/tutorials/getting-started/np/cheat-sheet.md b/docs/python_docs/python/tutorials/getting-started/np/cheat-sheet.md new file mode 100644 index 000000000000..7f4d82605653 --- /dev/null +++ b/docs/python_docs/python/tutorials/getting-started/np/cheat-sheet.md @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + +# The NP on MXNet cheat sheet + +To begin, import the `np` and `npx` module and update MXNet to run in +NumPy-like mode. + +```{.python .input n=1} +from mxnet import np, npx +npx.set_np() # Change MXNet to the numpy-like mode. +``` + +NDArray figure (TODO) + +## Creating arrays + +```{.python .input n=2} +np.array([1, 2, 3]) # default datatype is float32 +``` + +```{.python .input n=3} +np.array([(1.5, 2, 3), (4, 5, 6)], dtype='float16') +``` + +```{.python .input n=4} +np.array([[(15,2,3), (4,5,6)], [(3,2,1), (4,5,6)]], dtype='int32') +``` + +### Initial placeholders + +```{.python .input n=5} +np.zeros((3, 4)) # Create an array of zeros +``` + +```{.python .input n=6} +np.ones((2, 3, 4), dtype='int8') # Create an array of ones +``` + +```{.python .input n=7} +np.arange(10, 25, 5) # Create an array of evenly spaced values (step value) +``` + +```{.python .input n=8} +# Create an array of evenly spaced values (number of samples) +# np.linspace(0, 2, 9) +``` + +```{.python .input n=9} +# np.full((2, 2), 7) # Create a constant array +``` + +```{.python .input n=10} +# np.eye(2) # Create a 2X2 identity matrix +``` + +```{.python .input n=11} +# np.random.random((2, 2)) # Create an array with random values +``` + +```{.python .input n=12} +np.empty((3,2)) # Create an empty array +``` + +## I/O + +### Saving and loading on disk + +```{.python .input n=12} +# Save one array +a = np.array([1, 2, 3]) +npx.save('my_array', a) +npx.load('my_array') +``` + +```{.python .input n=20} +# Save a list of arrays +b = np.array([4, 6, 8]) +npx.save('my_arrays', [a, b]) # FIXME, cannot be a tuple +npx.load('my_arrays') +``` + +### Saving and loading text files + +```{.python .input n=20} +# np.loadtxt("myfile.txt") +# np.genfromtxt("my_file.csv", delimiter=',') +# np.savetxt("myarray.txt", a, delimiter=" ") +``` + +## Data types + +```{.python .input n=20} +# np.int64 # Signed 64-bit integer types +# np.float32 # Standard double-precision floating point +# np.complex # Complex numbers represented by 128 floats +# np.bool # Boolean type storing TRUE and FALSE values +# np.object # Python object type +# np.string_ # Fixed-length string type +# np.unicode_ # Fixed-length unicode type +``` + +## Inspecting your array + +```{.python .input n=21} +a.shape # Array dimensions +``` + +```{.python .input n=22} +len(a) # Length of array +``` + +```{.python .input n=23} +b.ndim # Number of array dimensions +``` + +```{.python .input n=24} +b.size # Number of array elements +``` + +```{.python .input n=25} +b.dtype # Data type of array elements +``` + +```{.python .input n=29} +# b.dtype.name # Name of data type +``` + +```{.python .input n=35} +b.astype('int') # Convert an array to a different type +``` + +## Asking For Help + +```{.python .input n=36} +# np.info(np.ndarray.dtype) +``` + +## Array mathematics + +### Arithmetic operations + +```{.python .input n=37} +a - b # Subtraction +``` + +```{.python .input n=38} +np.subtract(a, b) # Subtraction +``` + +```{.python .input n=39} +b + a # Addition +``` + +```{.python .input n=40} +np.add(b, a) # Addition +``` + +```{.python .input n=41} +a / b # Division +``` + +```{.python .input n=42} +np.divide(a,b) # Division +``` + +```{.python .input n=43} +a * b # Multiplication +``` + +```{.python .input n=44} +np.multiply(a, b) # Multiplication +``` + +```{.python .input n=45} +np.exp(b) # Exponentiation +``` + +```{.python .input n=46} +np.sqrt(b) # Square root +``` + +```{.python .input n=47} +np.sin(a) # Sines of an array +``` + +```{.python .input n=48} +np.cos(b) # Element-wise cosine +``` + +```{.python .input n=49} +np.log(a) # Element-wise natural logarithm +``` + +```{.python .input n=50} +a.dot(b) # Dot product +``` + +### Comparison + +### Aggregate functions + +```{.python .input n=51} +a.sum() # Array-wise sum +``` + +```{.python .input n=53} +# a.min() # Array-wise minimum value +``` + +```{.python .input n=57} +c = np.array(([[1,2,3], [2,3,4]])) +# c.max(axis=0) # Maximum value of an array row +``` + +```{.python .input n=56} +# c.cumsum(axis=1) # Cumulative sum of the elements +``` + +```{.python .input n=58} +a.mean() # Mean +``` + +```{.python .input n=60} +# b.median() # Median +``` + +```{.python .input n=61} +# a.corrcoef() # Correlation coefficient +``` + +```{.python .input n=63} +# np.std(b) # Standard deviation +``` + +## Copying arrays + +```{.python .input n=63} +# a.view() # Create a view of the array with the same data +``` + +```{.python .input n=63} +np.copy(a) # Create a copy of the array +``` + +```{.python .input n=63} +a.copy() # Create a deep copy of the array +``` + +## Sorting Arrays + +```{.python .input n=63} +# a.sort() # Sort an array +``` + +```{.python .input n=63} +# c.sort(axis=0) # Sort the elements of an array's axis +``` + +## Subsetting, slicing, indexing + +### Subsetting + +```{.python .input n=63} +a[2] # Select the element at the 2nd index 3 +``` + +```{.python .input n=63} +c[0,1] # Select the element at row 1 column 2 +``` + +### Slicing + +```{.python .input n=63} +a[0:2] # Select items at index 0 and 1 +``` + +```{.python .input n=63} +c[0:2,1] # Select items at rows 0 and 1 in column 1 +``` + +```{.python .input n=63} +c[:1] # Select all items at row 0 +``` + +```{.python .input n=63} +# c[1,...] # Same as [1,:,:] +``` + +```{.python .input n=63} +a[ : :-1] #Reversed array a array([3, 2, 1]) +``` + +### Boolean Indexing + +```{.python .input n=63} +# a[a<2] # Select elements from a less than 2 +``` + +### Fancy indexing + +```{.python .input n=63} +c[[1,0,1,0], [0,1,2,0]] # Select elements (1,0),(0,1),(1,2) and (0,0) +``` + +```{.python .input n=63} +c[[1,0,1,0]][:,[0,1,2,0]] # Select a subset of the matrix’s rows +``` + +## Array manipulation + +### Transposing array + +```{.python .input n=63} +np.transpose(c) # Permute array dimensions +``` + +```{.python .input n=63} +c.T # Permute array dimensions +``` + +### Changing array shape + +```{.python .input n=63} +# b.ravel() # Flatten the array +``` + +```{.python .input n=63} +# c.reshape(3,-2) # Reshape, but don’t change data +``` + +### Adding and removing elements + +```{.python .input n=63} +# c.resize((6,2)) # Return a new array with shape (6, 2) +``` + +```{.python .input n=63} +# np.append(h,g) # Append items to an array +``` + +```{.python .input n=63} +# np.insert(a, 1, 5) # Insert items in an array +``` + +```{.python .input n=63} +# np.delete(a, [1]) # Delete items from an array +``` + +### Combining arrays + +```{.python .input n=63} +np.concatenate((a,b),axis=0) # Concatenate arrays +``` + +```{.python .input n=63} +# np.vstack((a,b)) # Stack arrays vertically (row-wise) +``` + +```{.python .input n=63} +# np.r_[e,f] # Stack arrays vertically (row-wise) +``` + +```{.python .input n=63} +# np.hstack((e,f)) # Stack arrays horizontally (column-wise) +``` + +```{.python .input n=63} +# np.column_stack((a,d)) # Create stacked column-wise arrays +``` + +```{.python .input n=63} +# np.c_[a,d] # Create stacked column-wise arrays +``` + +### Splitting arrays + +```{.python .input n=63} +# np.hsplit(a,3) # Split the array horizontally at the 3rd index +``` + +```{.python .input n=63} +# np.vsplit(c,2) # Split the array vertically at the 2nd index +``` + +## Use GPUs + +Prerequisites: A GPU exists and GPU-enabled MXNet is installed. + +```{.python .input} +npx.num_gpus() # Query number of GPUs +``` + +```{.python .input} +npx.gpu(0), npx.gpu(1) # Context for the first and second GPUs +``` + +```{.python .input} +gpu_0 = npx.gpu(0) if npx.num_gpus() > 1 else npx.cpu() +g0 = np.zeros((2,3), ctx=gpu_0) # Create array on GPU 0 +g0 +``` + +```{.python .input} +gpu_1 = npx.gpu(1) if npx.num_gpus() > 2 else npx.cpu() +g1 = np.random.uniform(size=(2,3), ctx=gpu_1) # Create array on GPU 1 +g1 +``` + +```{.python .input} +# Copy to another GPU +g1.copyto(gpu_0) +``` + +```{.python .input} +# Return itself if matching the context, otherwise copy +g1.copyto(gpu_0), g1.copyto(gpu_0) +``` + +```{.python .input} +g1.context # Query the device an array is on +``` + +```{.python .input} +## The computation is performed by the devices on which the input arrays are +g0 + g1.copyto(gpu_0) +``` + +## Auto differentiation + +```{.python .input} +a.attach_grad() # Allocate gradient for a variable +a.grad # access the gradient +``` + +Compute the $\nabla_a b=\exp(2a)^T a$ + +```{.python .input} +from mxnet import autograd + +with autograd.record(): + b = np.exp(2*a).dot(a) +b.backward() +a.grad +``` + +**Acknowledgement** + +Adapted from www.datacamp.com. diff --git a/docs/python_docs/python/api/mxnet/executor_manager/index.rst b/docs/python_docs/python/tutorials/getting-started/np/index.rst similarity index 63% rename from docs/python_docs/python/api/mxnet/executor_manager/index.rst rename to docs/python_docs/python/tutorials/getting-started/np/index.rst index 2be59bdce8a5..3f1da88072a7 100644 --- a/docs/python_docs/python/api/mxnet/executor_manager/index.rst +++ b/docs/python_docs/python/tutorials/getting-started/np/index.rst @@ -15,9 +15,18 @@ specific language governing permissions and limitations under the License. -mxnet.executor_manager -====================== +What is NP on MXNet +===================== -.. automodule:: mxnet.executor_manager - :members: - :autosummary: +NP on MXNet provides a NumPy-like interface with extensions +for deep learning. It contains two modules, ``mxnet.np``, which is similar to +NumPy, and ``mxnet.npx``, which contains extended operators that are useful for deep +learning. + +If this is your first time using NP on MXNet, we recommend that you review the following topics in this section: + +.. toctree:: + :maxdepth: 1 + + cheat-sheet + np-vs-numpy \ No newline at end of file diff --git a/docs/python_docs/python/tutorials/getting-started/np/np-vs-numpy.md b/docs/python_docs/python/tutorials/getting-started/np/np-vs-numpy.md new file mode 100644 index 000000000000..60c87af3ee54 --- /dev/null +++ b/docs/python_docs/python/tutorials/getting-started/np/np-vs-numpy.md @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + +# Differences between NP on MXNet and NumPy + +This topic lists known differences between `mxnet.np` and `numpy`. With this quick reference, NumPy users can more easily adopt the MXNet NumPy-like API. + +```{.python .input} +import numpy as onp # o means original +from mxnet import np, npx +npx.set_np() # Configue MXNet to be NumPy-like +``` + +## Missing operators + +Many, but not all, operators in NumPy are supported in MXNet. You can find the missing operators in [NP on MXNet reference](/api/python/docs/api/ndarray/index.html). They're displayed in gray blocks instead of having links to their documents. + +In addition, an operator might not contain all arguments available in NumPy. For example, MXNet does not support stride. Check the operator document for more details. + +## Extra functionalities + +The `mxnet.np` module aims to mimic NumPy. Most extra functionalities that enhance NumPy for deep learning use are available on other modules, such as `npx` for operators used in deep learning and `autograd` for automatic differentiation. The `np` module API is not complete. One notable change is GPU support. Creating routines accepts a `ctx` argument: + +```{.python .input} +gpu = npx.gpu() if npx.num_gpus() > 0 else npx.cpu() +a = np.array(1, ctx=gpu) +b = np.random.uniform(ctx=gpu) +(a, b.context) +``` + +Methods to move data across devices. + +```{.python .input} +a.copyto(npx.cpu()), b.as_in_context(npx.cpu()) +``` + +## Default data types + +NumPy uses 64-bit floating numbers or 64-bit integers by default. + +```{.python .input} +onp.array([1,2]).dtype, onp.array([1.2,2.3]).dtype +``` + +MXNet uses 32-bit floating points as the default date type. It's the default data type for deep learning. + +```{.python .input} +np.array([1,2]).dtype, np.array([1.2,2.3]).dtype +``` + +## Scalars + +NumPy has classes for scalars, whose base class is 'numpy.generic'. The return values of selecting an element and reduce operators are scalars. + +```{.python .input} +a = onp.array([1,2]) +type(a[0]), type(a.sum()) +``` + +A scalar is almost identical to a 0-rank tensor (TODO, there may be subtle difference), but it has a different class. You can check the data type with `isinstance` + +```{.python .input} +b = a[0] +(b.ndim, b.size, isinstance(b, onp.generic), isinstance(b, onp.integer), + isinstance(b, onp.int64), isinstance(b, onp.ndarray)) +``` + +MXNet returns 0-rank `ndarray` for scalars. (TODO, may consider to add scalar classes later.) + +```{.python .input} +a = np.array([1,2]) +type(a[0]), type(a.sum()) +``` + +```{.python .input} +b = a[0] +b.ndim, b.size, isinstance(b, np.ndarray) +``` + +## Save + +The `save` method in `mxnet.np` saves data into a binary format that's not compatible with NumPy format. For example, it contains the device information. (TODO, needs more discussion here.) + +```{.python .input} +a = np.array(1, ctx=gpu) +npx.save('a', a) +npx.load('a') +``` + +## Matplotlib + +Sometimes the MXNet ndarray cannot used by other libraries that accept NumPy input, for example matplotlib. The best practice is converting to NumPy with `asnumpy()`. + +```{.python .input} +%matplotlib inline +import matplotlib.pyplot as plt + +plt.plot(np.array([1,2]).asnumpy()); +``` diff --git a/docs/python_docs/python/tutorials/index.rst b/docs/python_docs/python/tutorials/index.rst index 70f60c3c61a5..dcc5ea6dbfd6 100644 --- a/docs/python_docs/python/tutorials/index.rst +++ b/docs/python_docs/python/tutorials/index.rst @@ -48,11 +48,10 @@ Packages & Modules MXNet's imperative interface for Python. If you're new to MXNet, start here! .. card:: - :title: NDArray API - :link: packages/ndarray/index.html + :title: np.ndarray API + :link: packages/np/index.html - How to use the NDArray API to manipulate data. - A useful set of tutorials for beginners. + This section contains the `mxnet.np` API reference documentation. .. card:: :title: Symbol API diff --git a/docs/python_docs/python/tutorials/packages/index.rst b/docs/python_docs/python/tutorials/packages/index.rst index 370028a919d1..b14b884809a0 100644 --- a/docs/python_docs/python/tutorials/packages/index.rst +++ b/docs/python_docs/python/tutorials/packages/index.rst @@ -91,6 +91,12 @@ Shared APIs How to use the optimizers. + .. card:: + :title: NP on MXNet reference + :link: np/index.html + + This section contains the mxnet.np API reference documentation. + .. toctree:: :hidden: :glob: diff --git a/docs/python_docs/python/tutorials/packages/ndarray/index.rst b/docs/python_docs/python/tutorials/packages/ndarray/index.rst index 41b82091fdc2..5fb5e5d1d94f 100644 --- a/docs/python_docs/python/tutorials/packages/ndarray/index.rst +++ b/docs/python_docs/python/tutorials/packages/ndarray/index.rst @@ -45,10 +45,11 @@ NDArray For Sparse NDArray tutorials + This section contains the mxnet.np API reference documentation .. toctree:: :hidden: :glob: * - sparse/index \ No newline at end of file + sparse/index diff --git a/docs/python_docs/python/tutorials/packages/np/arrays.indexing.rst b/docs/python_docs/python/tutorials/packages/np/arrays.indexing.rst new file mode 100644 index 000000000000..e073d2100454 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/arrays.indexing.rst @@ -0,0 +1,356 @@ +.. _arrays.indexing: + +Indexing +======== + +.. sectionauthor:: adapted from "Guide to NumPy" by Travis E. Oliphant + +.. currentmodule:: mxnet.np + +.. index:: indexing, slicing + +:class:`ndarrays ` can be indexed using the standard Python +``x[obj]`` syntax, where *x* is the array and *obj* the selection. +There are three kinds of indexing available: basic +slicing, advanced indexing, and boolean mask indexing. Which one occurs depends on *obj*. + +.. note:: + + In Python, ``x[(exp1, exp2, ..., expN)]`` is equivalent to + ``x[exp1, exp2, ..., expN]``; the latter is just syntactic sugar + for the former. + + +Basic Slicing and Indexing +-------------------------- + +Basic slicing extends Python's basic concept of slicing to N +dimensions. Basic slicing occurs when *obj* is a :class:`slice` object +(constructed by ``start:stop:step`` notation inside of brackets), an +integer, or a tuple of slice objects and integers. :const:`Ellipsis` +and :const:`newaxis` objects can be interspersed with these as +well. + +The simplest case of indexing with *N* integers returns an :ref:`array +scalar ` representing the corresponding item. As in +Python, all indices are zero-based: for the *i*-th index :math:`n_i`, +the valid range is :math:`0 \le n_i < d_i` where :math:`d_i` is the +*i*-th element of the shape of the array. Negative indices are +interpreted as counting from the end of the array (*i.e.*, if +:math:`n_i < 0`, it means :math:`n_i + d_i`). + +All arrays generated by basic slicing are always :term:`views ` +of the original array if the fetched elements are contiguous in memory. + +The standard rules of sequence slicing apply to basic slicing on a +per-dimension basis (including using a step index). Some useful +concepts to remember include: + +- The basic slice syntax is ``i:j:k`` where *i* is the starting index, + *j* is the stopping index, and *k* is the step (:math:`k\neq0`). + This selects the *m* elements (in the corresponding dimension) with + index values *i*, *i + k*, ..., *i + (m - 1) k* where + :math:`m = q + (r\neq0)` and *q* and *r* are the quotient and remainder + obtained by dividing *j - i* by *k*: *j - i = q k + r*, so that + *i + (m - 1) k < j*. + + .. admonition:: Example + + >>> x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) + >>> x[1:7:2] + array([1, 3, 5]) + +- Negative *i* and *j* are interpreted as *n + i* and *n + j* where + *n* is the number of elements in the corresponding dimension. + Negative *k* makes stepping go towards smaller indices. + + .. admonition:: Example + + >>> x[-2:10] + array([8, 9]) + >>> x[-3:3:-1] + array([7, 6, 5, 4]) + +- Assume *n* is the number of elements in the dimension being + sliced. Then, if *i* is not given it defaults to 0 for *k > 0* and + *n - 1* for *k < 0* . If *j* is not given it defaults to *n* for *k > 0* + and *-n-1* for *k < 0* . If *k* is not given it defaults to 1. Note that + ``::`` is the same as ``:`` and means select all indices along this + axis. + + .. admonition:: Example + + >>> x[5:] + array([5, 6, 7, 8, 9]) + +- If the number of objects in the selection tuple is less than + *N* , then ``:`` is assumed for any subsequent dimensions. + + .. admonition:: Example + + >>> x = np.array([[[1],[2],[3]], [[4],[5],[6]]]) + >>> x.shape + (2, 3, 1) + >>> x[1:2] + array([[[4], + [5], + [6]]]) + +- :const:`Ellipsis` expands to the number of ``:`` objects needed for the + selection tuple to index all dimensions. In most cases, this means that + length of the expanded selection tuple is ``x.ndim``. There may only be a + single ellipsis present. + + .. admonition:: Example + + >>> x[...,0] + array([[1, 2, 3], + [4, 5, 6]]) + +- Each :const:`newaxis` object in the selection tuple serves to expand + the dimensions of the resulting selection by one unit-length + dimension. The added dimension is the position of the :const:`newaxis` + object in the selection tuple. + + .. admonition:: Example + + >>> x[:,np.newaxis,:,:].shape + (2, 1, 3, 1) + +- An integer, *i*, returns the same values as ``i:i+1`` + **except** the dimensionality of the returned object is reduced by + 1. In particular, a selection tuple with the *p*-th + element an integer (and all other entries ``:``) returns the + corresponding sub-array with dimension *N - 1*. If *N = 1* + then the returned object is an scalar `ndarray` whose `ndim=0`. + +- If the selection tuple has all entries ``:`` except the + *p*-th entry which is a slice object ``i:j:k``, + then the returned array has dimension *N* formed by + concatenating the sub-arrays returned by integer indexing of + elements *i*, *i+k*, ..., *i + (m - 1) k < j*, + +- Basic slicing with more than one non-``:`` entry in the slicing + tuple, acts like repeated application of slicing using a single + non-``:`` entry, where the non-``:`` entries are successively taken + (with all other non-``:`` entries replaced by ``:``). Thus, + ``x[ind1,...,ind2,:]`` acts like ``x[ind1][...,ind2,:]`` under basic + slicing. + + .. warning:: The above is **not** true for advanced indexing. + +- You may use slicing to set values in the array, but (unlike lists) you + can never grow the array. The size of the value to be set in + ``x[obj] = value`` must be (broadcastable) to the same shape as + ``x[obj]``. + +.. note:: + + Remember that a slicing tuple can always be constructed as *obj* + and used in the ``x[obj]`` notation. Slice objects can be used in + the construction in place of the ``[start:stop:step]`` + notation. For example, ``x[1:10:5,::-1]`` can also be implemented + as ``obj = (slice(1,10,5), slice(None,None,-1)); x[obj]`` . This + can be useful for constructing generic code that works on arrays + of arbitrary dimension. + +.. data:: newaxis + :noindex: + + The :const:`newaxis` object can be used in all slicing operations to + create an axis of length one. :const:`newaxis` is an alias for + 'None', and 'None' can be used in place of this with the same result. + + +Advanced Indexing +----------------- + +Advanced indexing is triggered when the selection object, *obj*, is a +non-tuple sequence object, an :class:`ndarray` (of data type integer or bool), +or a tuple with at least one sequence object or ndarray (of data type +integer or bool). There are two types of advanced indexing: integer +and Boolean. + +Advanced indexing always returns a *copy* of the data (contrast with +some cases in basic slicing that returns a :term:`view`). + +.. warning:: + + The definition of advanced indexing means that ``x[(1,2,3),]`` is + fundamentally different than ``x[(1,2,3)]``. The latter is + equivalent to ``x[1,2,3]`` which will trigger basic selection while + the former will trigger advanced indexing. Be sure to understand + why this occurs. + + Also recognize that ``x[[1,2,3]]`` will trigger advanced indexing, + whereas due to the deprecated Numeric compatibility mentioned above, + ``x[[1,2,slice(None)]]`` will trigger basic slicing in the official NumPy + which is not currently supported in MXNet `numpy` module. + +Integer array indexing +^^^^^^^^^^^^^^^^^^^^^^ + +Integer array indexing allows selection of arbitrary items in the array +based on their *N*-dimensional index. Each integer array represents a number +of indexes into that dimension. + +Purely integer array indexing +""""""""""""""""""""""""""""" + +When the index consists of as many integer arrays as the array being indexed +has dimensions, the indexing is straight forward, but different from slicing. + +Advanced indexes always are broadcasting and +iterated as *one*:: + + result[i_1, ..., i_M] == x[ind_1[i_1, ..., i_M], ind_2[i_1, ..., i_M], + ..., ind_N[i_1, ..., i_M]] + +Note that the result shape is identical to the (broadcast) indexing array +shapes ``ind_1, ..., ind_N``. + +.. admonition:: Example + + From each row, a specific element should be selected. The row index is just + ``[0, 1, 2]`` and the column index specifies the element to choose for the + corresponding row, here ``[0, 1, 0]``. Using both together the task + can be solved using advanced indexing: + + >>> x = np.array([[1, 2], [3, 4], [5, 6]]) + >>> x[[0, 1, 2], [0, 1, 0]] + array([1, 4, 5]) + +Combining advanced and basic indexing +""""""""""""""""""""""""""""""""""""" + +When there is at least one slice (``:``), ellipsis (``...``) or :const:`newaxis` +in the index (or the array has more dimensions than there are advanced indexes), +then the behaviour can be more complicated. It is like concatenating the +indexing result for each advanced index element + +In the simplest case, there is only a *single* advanced index. A single +advanced index can for example replace a slice and the result array will be +the same, however, it is a copy and may have a different memory layout. +A slice is preferable when it is possible. + +.. admonition:: Example + + >>> x[1:2, 1:3] + array([[4, 5]]) + >>> x[1:2, [1, 2]] + array([[4, 5]]) + +The easiest way to understand the situation may be to think in +terms of the result shape. There are two parts to the indexing operation, +the subspace defined by the basic indexing (excluding integers) and the +subspace from the advanced indexing part. Two cases of index combination +need to be distinguished: + +* The advanced indexes are separated by a slice, :const:`Ellipsis` or :const:`newaxis`. + For example ``x[arr1, :, arr2]``. +* The advanced indexes are all next to each other. + For example ``x[..., arr1, arr2, :]`` but *not* ``x[arr1, :, 1]`` + since ``1`` is an advanced index in this regard. + +In the first case, the dimensions resulting from the advanced indexing +operation come first in the result array, and the subspace dimensions after +that. +In the second case, the dimensions from the advanced indexing operations +are inserted into the result array at the same spot as they were in the +initial array (the latter logic is what makes simple advanced indexing +behave just like slicing). + +.. admonition:: Example + + Suppose ``x.shape`` is (10,20,30) and ``ind`` is a (2,3,4)-shaped + indexing :class:`intp` array, then ``result = x[...,ind,:]`` has + shape (10,2,3,4,30) because the (20,)-shaped subspace has been + replaced with a (2,3,4)-shaped broadcasted indexing subspace. If + we let *i, j, k* loop over the (2,3,4)-shaped subspace then + ``result[...,i,j,k,:] = x[...,ind[i,j,k],:]``. This example + produces the same result as :meth:`x.take(ind, axis=-2) `. + +.. admonition:: Example + + Let ``x.shape`` be (10,20,30,40,50) and suppose ``ind_1`` + and ``ind_2`` can be broadcast to the shape (2,3,4). Then + ``x[:,ind_1,ind_2]`` has shape (10,2,3,4,40,50) because the + (20,30)-shaped subspace from X has been replaced with the + (2,3,4) subspace from the indices. However, + ``x[:,ind_1,:,ind_2]`` has shape (2,3,4,10,30,50) because there + is no unambiguous place to drop in the indexing subspace, thus + it is tacked-on to the beginning. It is always possible to use + :meth:`.transpose() ` to move the subspace + anywhere desired. Note that this example cannot be replicated + using :func:`take`. + + +Boolean array indexing +^^^^^^^^^^^^^^^^^^^^^^ + +This advanced indexing occurs when obj is an array object of Boolean +type, such as may be returned from comparison operators. A single +boolean index array is practically identical to ``x[obj.nonzero()]`` where, +as described above, :meth:`obj.nonzero() ` returns a +tuple (of length :attr:`obj.ndim `) of integer index +arrays showing the :const:`True` elements of *obj*. However, it is +faster when ``obj.shape == x.shape``. + +If ``obj.ndim == x.ndim``, ``x[obj]`` returns a 1-dimensional array +filled with the elements of *x* corresponding to the :const:`True` +values of *obj*. The search order will be :term:`row-major`, +C-style. If *obj* has :const:`True` values at entries that are outside +of the bounds of *x*, then an index error will be raised. If *obj* is +smaller than *x* it is identical to filling it with :const:`False`. + +.. note:: + +Boolean indexing currently only supports a single boolean ndarray as a index. +An composite index including a boolean array is not supported for now. + +If there is only one Boolean array and no integer indexing array present, +this is straight forward. Care must only be taken to make sure that the +boolean index has *exactly* as many dimensions as it is supposed to work +with. + +.. admonition:: Example + + From an array, select all rows which sum up to less or equal two: + + >>> x = np.array([[0, 1], [1, 1], [2, 2]], dtype=np.int32) + >>> rowsum = x.sum(-1) + >>> x[rowsum <= 2] + array([[0, 1], + [1, 1]], dtype=int32) + + But if ``rowsum`` would have two dimensions as well: + + >>> rowsum = x.sum(-1, keepdims=True) + >>> rowsum.shape + (3, 1) + >>> x[rowsum <= 2] # fail + IndexError: boolean index did not match indexed array along dimension 1 + +Detailed notes +-------------- + +These are some detailed notes, which are not of importance for day to day +indexing (in no particular order): + +* For advanced assignments, there is in general no guarantee for the + iteration order. This means that if an element is set more than once, + it is not possible to predict the final result. +* An empty (tuple) index is a full scalar index into a zero dimensional array. + ``x[()]`` returns a *scalar* `ndarray` if ``x`` has zero dimensions. + On the other hand ``x[...]`` always returns a view. +* If a zero dimensional array is present in the index *and* it is *not considered as* a full + integer index as in NumPy. Advanced indexing is not triggered. +* the ``nonzero`` equivalence for Boolean arrays does not hold for zero + dimensional boolean arrays. +* When the result of an advanced indexing operation has no elements but an + individual index is out of bounds, currently no ``IndexError`` is + raised as in NumPy. + +.. index:: + single: indexing + single: ndarray diff --git a/docs/python_docs/python/tutorials/packages/np/arrays.ndarray.rst b/docs/python_docs/python/tutorials/packages/np/arrays.ndarray.rst new file mode 100644 index 000000000000..a0e9a8707010 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/arrays.ndarray.rst @@ -0,0 +1,631 @@ +.. _arrays.ndarray: + +****************************************** +The N-dimensional array (:class:`ndarray`) +****************************************** + +.. currentmodule:: mxnet.np + +An :class:`ndarray` is a (usually fixed-size) multidimensional +container of items of the same type and size. The number of dimensions +and items in an array is defined by its :attr:`shape `, +which is a :class:`tuple` of *N* non-negative integers that specify the +sizes of each dimension. The type of items in the array is specified by +a separate :ref:`data-type object (dtype) `, one of which +is associated with each ndarray. + +As with other container objects in Python, the contents of an +:class:`ndarray` can be accessed and modified by :ref:`indexing or +slicing ` the array (using, for example, *N* integers), +and via the methods and attributes of the :class:`ndarray`. + +.. index:: view, base + +Different :class:`ndarrays ` can share the same data, so that +changes made in one :class:`ndarray` may be visible in another. That +is, an ndarray can be a *"view"* to another ndarray, and the data it +is referring to is taken care of by the *"base"* ndarray. + + +.. admonition:: Example + + A 2-dimensional array of size 2 x 3, composed of 4-byte integer + elements: + + >>> x = np.array([[1, 2, 3], [4, 5, 6]], np.int32) + >>> type(x) + + >>> x.shape + (2, 3) + >>> x.dtype + dtype('int32') + + The array can be indexed using Python container-like syntax: + + >>> # The element of x in the *second* row, *third* column, namely, 6. + >>> x[1, 2] + array(6, dtype=int32) # this is different than the official NumPy which returns a np.int32 object + + For example :ref:`slicing ` can produce views of + the array if the elements to be sliced is continguous in memory: + + >>> y = x[1,:] + >>> y + array([9, 5, 6], dtype=int32) # this also changes the corresponding element in x + >>> x + array([[1, 2, 3], + [9, 5, 6]], dtype=int32) + + +Constructing arrays +=================== + +New arrays can be constructed using the routines detailed in +:ref:`routines.array-creation`, and also by using the low-level +:class:`ndarray` constructor: + +.. autosummary:: + :toctree: generated/ + + ndarray + +:: + + +Indexing arrays +=============== + +Arrays can be indexed using an extended Python slicing syntax, +``array[selection]``. Similar syntax is also used for accessing +fields in a :term:`structured data type`. + +.. seealso:: :ref:`Array Indexing `. + +.. _memory-layout: + +Internal memory layout of an ndarray +==================================== + +An instance of class :class:`ndarray` consists of a contiguous +one-dimensional segment of computer memory (owned by the array, or by +some other object), combined with an indexing scheme that maps *N* +integers into the location of an item in the block. The ranges in +which the indices can vary is specified by the :obj:`shape +` of the array. How many bytes each item takes and how +the bytes are interpreted is defined by the :ref:`data-type object +` associated with the array. + +.. index:: C-order, Fortran-order, row-major, column-major, stride, + offset + +.. note:: + + `mxnet.numpy.ndarray` currently only supports storing elements in + C-order/row-major and contiguous memory space. The following content + on explaining a variety of memory layouts of an ndarray + are copied from the official NumPy documentation as a comprehensive reference. + +A segment of memory is inherently 1-dimensional, and there are many +different schemes for arranging the items of an *N*-dimensional array +in a 1-dimensional block. NumPy is flexible, and :class:`ndarray` +objects can accommodate any *strided indexing scheme*. In a strided +scheme, the N-dimensional index :math:`(n_0, n_1, ..., n_{N-1})` +corresponds to the offset (in bytes): + +.. math:: n_{\mathrm{offset}} = \sum_{k=0}^{N-1} s_k n_k + +from the beginning of the memory block associated with the +array. Here, :math:`s_k` are integers which specify the :obj:`strides +` of the array. The :term:`column-major` order (used, +for example, in the Fortran language and in *Matlab*) and +:term:`row-major` order (used in C) schemes are just specific kinds of +strided scheme, and correspond to memory that can be *addressed* by the strides: + +.. math:: + + s_k^{\mathrm{column}} = \mathrm{itemsize} \prod_{j=0}^{k-1} d_j , + \quad s_k^{\mathrm{row}} = \mathrm{itemsize} \prod_{j=k+1}^{N-1} d_j . + +.. index:: single-segment, contiguous, non-contiguous + +where :math:`d_j` `= self.shape[j]`. + +Both the C and Fortran orders are :term:`contiguous`, *i.e.,* +single-segment, memory layouts, in which every part of the +memory block can be accessed by some combination of the indices. + +While a C-style and Fortran-style contiguous array, which has the corresponding +flags set, can be addressed with the above strides, the actual strides may be +different. This can happen in two cases: + + 1. If ``self.shape[k] == 1`` then for any legal index ``index[k] == 0``. + This means that in the formula for the offset :math:`n_k = 0` and thus + :math:`s_k n_k = 0` and the value of :math:`s_k` `= self.strides[k]` is + arbitrary. + 2. If an array has no elements (``self.size == 0``) there is no legal + index and the strides are never used. Any array with no elements may be + considered C-style and Fortran-style contiguous. + +Point 1. means that ``self`` and ``self.squeeze()`` always have the same +contiguity and ``aligned`` flags value. This also means +that even a high dimensional array could be C-style and Fortran-style +contiguous at the same time. + +.. index:: aligned + +An array is considered aligned if the memory offsets for all elements and the +base offset itself is a multiple of `self.itemsize`. Understanding +`memory-alignment` leads to better performance on most hardware. + +.. note:: + + Points (1) and (2) are not yet applied by default. Beginning with + NumPy 1.8.0, they are applied consistently only if the environment + variable ``NPY_RELAXED_STRIDES_CHECKING=1`` was defined when NumPy + was built. Eventually this will become the default. + + You can check whether this option was enabled when your NumPy was + built by looking at the value of ``np.ones((10,1), + order='C').flags.f_contiguous``. If this is ``True``, then your + NumPy has relaxed strides checking enabled. + +.. warning:: + + It does *not* generally hold that ``self.strides[-1] == self.itemsize`` + for C-style contiguous arrays or ``self.strides[0] == self.itemsize`` for + Fortran-style contiguous arrays is true. + +Data in new :class:`ndarrays ` is in the :term:`row-major` +(C) order, unless otherwise specified, but, for example, :ref:`basic +array slicing ` often produces :term:`views ` +in a different scheme. + +.. seealso: :ref:`Indexing `_ + +.. note:: + + Several algorithms in NumPy work on arbitrarily strided arrays. + However, some algorithms require single-segment arrays. When an + irregularly strided array is passed in to such algorithms, a copy + is automatically made. + +.. _arrays.ndarray.attributes: + +Array attributes +================ + +Array attributes reflect information that is intrinsic to the array +itself. Generally, accessing an array through its attributes allows +you to get and sometimes set intrinsic properties of the array without +creating a new array. The exposed attributes are the core parts of an +array and only some of them can be reset meaningfully without creating +a new array. Information on each attribute is given below. + +Memory layout +------------- + +The following attributes contain information about the memory layout +of the array: + +.. autosummary:: + :toctree: generated/ + + ndarray.shape + ndarray.ndim + ndarray.size + +:: + + ndarray.flags + ndarray.strides + ndarray.data + ndarray.itemsize + ndarray.nbytes + ndarray.base + +Data type +--------- + +.. seealso:: :ref:`Data type objects ` + +The data type object associated with the array can be found in the +:attr:`dtype ` attribute: + +.. autosummary:: + :toctree: generated/ + + ndarray.dtype + +Other attributes +---------------- + +.. autosummary:: + :toctree: generated/ + + ndarray.T + +:: + + ndarray.real + ndarray.imag + ndarray.flat + ndarray.ctypes + +.. _array.ndarray.methods: + +Array methods +============= + +An :class:`ndarray` object has many methods which operate on or with +the array in some fashion, typically returning an array result. These +methods are briefly explained below. (Each method's docstring has a +more complete description.) + +For the following methods there are also corresponding functions in +:mod:`numpy`: :func:`all`, :func:`any`, :func:`argmax`, +:func:`argmin`, :func:`argpartition`, :func:`argsort`, :func:`choose`, +:func:`clip`, :func:`compress`, :func:`copy`, :func:`cumprod`, +:func:`cumsum`, :func:`diagonal`, :func:`imag`, :func:`max `, +:func:`mean`, :func:`min `, :func:`nonzero`, :func:`partition`, +:func:`prod`, :func:`ptp`, :func:`put`, :func:`ravel`, :func:`real`, +:func:`repeat`, :func:`reshape`, :func:`round `, +:func:`searchsorted`, :func:`sort`, :func:`squeeze`, :func:`std`, +:func:`sum`, :func:`swapaxes`, :func:`take`, :func:`trace`, +:func:`transpose`, :func:`var`. + +Array conversion +---------------- + +.. autosummary:: + :toctree: generated/ + + ndarray.item + ndarray.copy + ndarray.tolist + ndarray.astype + +:: + + ndarray.itemset + ndarray.tostring + ndarray.tobytes + ndarray.tofile + ndarray.dump + ndarray.dumps + ndarray.byteswap + ndarray.view + ndarray.getfield + ndarray.setflags + ndarray.fill + +Shape manipulation +------------------ + +For reshape, resize, and transpose, the single tuple argument may be +replaced with ``n`` integers which will be interpreted as an n-tuple. + +.. autosummary:: + :toctree: generated/ + + ndarray.reshape + ndarray.transpose + ndarray.swapaxes + ndarray.flatten + ndarray.squeeze + +:: + + ndarray.resize + ndarray.ravel + +Item selection and manipulation +------------------------------- + +For array methods that take an *axis* keyword, it defaults to +:const:`None`. If axis is *None*, then the array is treated as a 1-D +array. Any other value for *axis* represents the dimension along which +the operation should proceed. + +.. autosummary:: + :toctree: generated/ + + ndarray.nonzero + ndarray.take + ndarray.repeat + + +:: + + ndarray.argsort + ndarray.sort + ndarray.put + ndarray.choose + ndarray.partition + ndarray.argpartition + ndarray.searchsorted + ndarray.compress + ndarray.diagonal + +Calculation +----------- + +.. index:: axis + +Many of these methods take an argument named *axis*. In such cases, + +- If *axis* is *None* (the default), the array is treated as a 1-D + array and the operation is performed over the entire array. This + behavior is also the default if self is a 0-dimensional array or + array scalar. (An array scalar is an instance of the types/classes + float32, float64, etc., whereas a 0-dimensional array is an ndarray + instance containing precisely one array scalar.) + +- If *axis* is an integer, then the operation is done over the given + axis (for each 1-D subarray that can be created along the given axis). + +.. admonition:: Example of the *axis* argument + + A 3-dimensional array of size 3 x 3 x 3, summed over each of its + three axes + + >>> x + array([[[ 0, 1, 2], + [ 3, 4, 5], + [ 6, 7, 8]], + [[ 9, 10, 11], + [12, 13, 14], + [15, 16, 17]], + [[18, 19, 20], + [21, 22, 23], + [24, 25, 26]]]) + >>> x.sum(axis=0) + array([[27, 30, 33], + [36, 39, 42], + [45, 48, 51]]) + >>> # for sum, axis is the first keyword, so we may omit it, + >>> # specifying only its value + >>> x.sum(0), x.sum(1), x.sum(2) + (array([[27, 30, 33], + [36, 39, 42], + [45, 48, 51]]), + array([[ 9, 12, 15], + [36, 39, 42], + [63, 66, 69]]), + array([[ 3, 12, 21], + [30, 39, 48], + [57, 66, 75]])) + +The parameter *dtype* specifies the data type over which a reduction +operation (like summing) should take place. The default reduce data +type is the same as the data type of *self*. To avoid overflow, it can +be useful to perform the reduction using a larger data type. + +For several methods, an optional *out* argument can also be provided +and the result will be placed into the output array given. The *out* +argument must be an :class:`ndarray` and have the same number of +elements. It can have a different data type in which case casting will +be performed. + +.. autosummary:: + :toctree: generated/ + + ndarray.max + ndarray.argmax + ndarray.min + ndarray.argmin + ndarray.clip + ndarray.sum + ndarray.mean + ndarray.prod + ndarray.cumsum + ndarray.var + ndarray.std + +:: + + ndarray.round + ndarray.ptp + ndarray.conj + ndarray.trace + ndarray.cumprod + ndarray.all + ndarray.any + +Arithmetic, matrix multiplication, and comparison operations +============================================================ + +.. index:: comparison, arithmetic, matrix, operation, operator + +Arithmetic and comparison operations on :class:`ndarrays ` +are defined as element-wise operations, and generally yield +:class:`ndarray` objects as results. + +Each of the arithmetic operations (``+``, ``-``, ``*``, ``/``, ``//``, +``%``, ``divmod()``, ``**`` or ``pow()``, ``<<``, ``>>``, ``&``, +``^``, ``|``, ``~``) and the comparisons (``==``, ``<``, ``>``, +``<=``, ``>=``, ``!=``) is equivalent to the corresponding +universal function (or :term:`ufunc` for short) in NumPy. For +more information, see the section on :ref:`Universal Functions +`. + +Comparison operators: + +.. autosummary:: + :toctree: generated/ + + ndarray.__lt__ + ndarray.__le__ + ndarray.__gt__ + ndarray.__ge__ + ndarray.__eq__ + ndarray.__ne__ + +Truth value of an array (:func:`bool()`): + +.. autosummary:: + :toctree: generated/ + + ndarray.__bool__ + +.. note:: + + Truth-value testing of an array invokes + :meth:`ndarray.__bool__`, which raises an error if the number of + elements in the array is larger than 1, because the truth value + of such arrays is ambiguous. + + +Unary operations: + +.. autosummary:: + :toctree: generated/ + + ndarray.__neg__ + +:: + + ndarray.__pos__ + ndarray.__abs__ + ndarray.__invert__ + +Arithmetic: + +.. autosummary:: + :toctree: generated/ + + ndarray.__add__ + ndarray.__sub__ + ndarray.__mul__ + ndarray.__truediv__ + ndarray.__mod__ + ndarray.__pow__ + +:: + + ndarray.__floordiv__ + ndarray.__divmod__ + ndarray.__lshift__ + ndarray.__rshift__ + ndarray.__and__ + ndarray.__or__ + ndarray.__xor__ + +.. note:: + + - Any third argument to :func:`pow()` is silently ignored, + as the underlying :func:`ufunc ` takes only two arguments. + + - The three division operators are all defined; :obj:`div` is active + by default, :obj:`truediv` is active when + :obj:`__future__` division is in effect. + + - Because :class:`ndarray` is a built-in type (written in C), the + ``__r{op}__`` special methods are not directly defined. + + - The functions called to implement many arithmetic special methods + for arrays can be modified using :class:`__array_ufunc__ `. + +Arithmetic, in-place: + +.. autosummary:: + :toctree: generated/ + + ndarray.__iadd__ + ndarray.__isub__ + ndarray.__imul__ + ndarray.__itruediv__ + ndarray.__imod__ + +:: + + ndarray.__ifloordiv__ + ndarray.__ipow__ + ndarray.__ilshift__ + ndarray.__irshift__ + ndarray.__iand__ + ndarray.__ior__ + ndarray.__ixor__ + +.. warning:: + + In place operations will perform the calculation using the + precision decided by the data type of the two operands, but will + silently downcast the result (if necessary) so it can fit back into + the array. Therefore, for mixed precision calculations, ``A {op}= + B`` can be different than ``A = A {op} B``. For example, suppose + ``a = ones((3,3))``. Then, ``a += 3j`` is different than ``a = a + + 3j``: while they both perform the same computation, ``a += 3`` + casts the result to fit back in ``a``, whereas ``a = a + 3j`` + re-binds the name ``a`` to the result. + +Matrix Multiplication: + +.. autosummary:: + :toctree: generated/ + +:: + + ndarray.__matmul__ + + +Special methods +=============== + +For standard library functions: + +.. autosummary:: + :toctree: generated/ + + ndarray.__reduce__ + ndarray.__setstate__ + +:: + + ndarray.__copy__ + ndarray.__deepcopy__ + +Basic customization: + +.. autosummary:: + :toctree: generated/ + +:: + + ndarray.__array__ + ndarray.__new__ + ndarray.__array_wrap__ + +Container customization: (see :ref:`Indexing `) + +.. autosummary:: + :toctree: generated/ + + ndarray.__len__ + ndarray.__getitem__ + ndarray.__setitem__ + +:: + + ndarray.__contains__ + +Conversion; the operations :func:`int()` and :func:`float()`. +They work only on arrays that have one element in them +and return the appropriate scalar. + +.. autosummary:: + :toctree: generated/ + + ndarray.__int__ + ndarray.__float__ + +:: + + ndarray.__complex__ + +String representations: + +.. autosummary:: + :toctree: generated/ + + ndarray.__str__ + ndarray.__repr__ diff --git a/docs/python_docs/python/tutorials/packages/np/arrays.rst b/docs/python_docs/python/tutorials/packages/np/arrays.rst new file mode 100644 index 000000000000..3f2a52620a51 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/arrays.rst @@ -0,0 +1,42 @@ +.. _arrays: + +************* +Array objects +************* + +.. currentmodule:: mxnet.np + +``np`` provides an N-dimensional array type, the :ref:`ndarray +`, which describes a collection of "items" of the same +type. The items can be :ref:`indexed ` using for +example N integers. + +All ndarrays are :term:`homogenous`: every item takes up the same size +block of memory, and all blocks are interpreted in exactly the same +way. How each item in the array is to be interpreted is specified by a +separate :ref:`data-type object `, one of which is associated +with every array. In addition to basic types (integers, floats, +*etc.*), the data type objects can also represent data structures. + +An item extracted from an array, *e.g.*, by indexing, is represented +by a Python object whose type is one of the :ref:`array scalar types +` built in NumPy. The array scalars allow easy manipulation +of also more complicated arrangements of data. + +.. note:: + + A major difference to ``numpy.ndarray`` is that ``mxnet.np.ndarray``'s scalar + is a 0-dim ndarray instead of a scalar object (``numpy.generic``). + +.. toctree:: + :maxdepth: 2 + + arrays.ndarray + arrays.scalars + arrays.dtypes + arrays.indexing + arrays.nditer + arrays.classes + maskedarray + arrays.interface + arrays.datetime diff --git a/docs/python_docs/python/tutorials/packages/np/index.rst b/docs/python_docs/python/tutorials/packages/np/index.rst new file mode 100644 index 000000000000..7830a4469b61 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/index.rst @@ -0,0 +1,30 @@ +.. _reference: + +NP on MXNet reference +============================ + + +.. module:: mxnet.np + +This section contains the `mxnet.np` API reference documentation. The topics here explain the functions, modules, and objects +included in `mxnet.np`. Use the links here to learn more. + + +.. toctree:: + :maxdepth: 2 + + arrays + constants + ufuncs + routines + distutils + distutils_guide + c-api + internals + swig + npx + + +**Acknowledgements** + +Large parts of this manual originate from NumPy documents. diff --git a/docs/python_docs/python/tutorials/packages/np/npx.rst b/docs/python_docs/python/tutorials/packages/np/npx.rst new file mode 100644 index 000000000000..dc0a4a08a6b1 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/npx.rst @@ -0,0 +1,85 @@ +NP Extensions +==================== + +.. currentmodule:: mxnet.npx + +Compatibility +------------- + +.. autosummary:: + :toctree: generated/ + + set_np + reset_np + +.. code:: + + is_np_array + use_np_array + is_np_shape + use_np_shape + np_array + np_shape + + +Devices +--------- + + +.. autosummary:: + :toctree: generated/ + + cpu + cpu_pinned + gpu + gpu_memory_info + current_context + num_gpus + +Nerual networks +----------------------- + +.. autosummary:: + :toctree: generated/ + + activation + batch_norm + convolution + dropout + embedding + fully_connected + layer_norm + pooling + rnn + leaky_relu + multibox_detection + multibox_prior + multibox_target + roi_pooling + + +More operators +------------------ + +.. autosummary:: + :toctree: generated/ + + sigmoid + smooth_l1 + softmax + threading + topk + waitall + load + save + one_hot + pick + reshape_like + batch_flatten + batch_dot + gamma + sequence_mask + +.. code:: + + seed \ No newline at end of file diff --git a/docs/python_docs/python/tutorials/packages/np/random/index.rst b/docs/python_docs/python/tutorials/packages/np/random/index.rst new file mode 100644 index 000000000000..0142b19c2775 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/random/index.rst @@ -0,0 +1,90 @@ +.. _numpyrandom: + +.. currentmodule:: mxnet.np.random + +np.random +============ + +.. + remove a large part about generator here, this page contains a part of generator.rst + + +Accessing the BitGenerator +-------------------------- +.. autosummary:: + :toctree: generated/ + +:: + + bit_generator + +Simple random data +------------------ +.. autosummary:: + :toctree: generated/ + + choice + +:: + + random + integers + bytes + +Permutations +------------ +.. autosummary:: + :toctree: generated/ + + shuffle + +:: + + permutation + +Distributions +------------- +.. autosummary:: + :toctree: generated/ + + + normal + uniform + rand + randint + +:: + + beta + binomial + chisquare + dirichlet + exponential + f + gamma + geometric + gumbel + hypergeometric + laplace + logistic + lognormal + logseries + multinomial + multivariate_normal + negative_binomial + noncentral_chisquare + noncentral_f + pareto + poisson + power + rayleigh + standard_cauchy + standard_exponential + standard_gamma + standard_normal + standard_t + triangular + vonmises + wald + weibull + zipf diff --git a/docs/python_docs/python/tutorials/packages/np/routines.array-creation.rst b/docs/python_docs/python/tutorials/packages/np/routines.array-creation.rst new file mode 100644 index 000000000000..2033923e5e75 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.array-creation.rst @@ -0,0 +1,124 @@ +.. _routines.array-creation: + +Array creation routines +======================= + +.. seealso:: :ref:`Array creation ` + +.. currentmodule:: mxnet.np + +Ones and zeros +-------------- +.. autosummary:: + :toctree: generated/ + + eye + empty + full + identity + ones + ones_like + zeros + zeros_like + +.. code:: + + full_like + empty_like + +From existing data +------------------ +.. autosummary:: + :toctree: generated/ + + array + copy + +.. code:: + + asarray + asanyarray + ascontiguousarray + asmatrix + frombuffer + fromfile + fromfunction + fromiter + fromstring + loadtxt + +.. _routines.array-creation.rec: + +Creating record arrays (:mod:`np.rec`) +----------------------------------------- + +.. note:: :mod:`np.rec` is the preferred alias for + :mod:`np.core.records`. + +.. autosummary:: + :toctree: generated/ + +.. code:: + + core.records.array + core.records.fromarrays + core.records.fromrecords + core.records.fromstring + core.records.fromfile + +.. _routines.array-creation.char: + +Creating character arrays (:mod:`np.char`) +--------------------------------------------- + +.. note:: :mod:`np.char` is the preferred alias for + :mod:`np.core.defchararray`. + +.. autosummary:: + :toctree: generated/ + +.. code:: + + core.defchararray.array + core.defchararray.asarray + +Numerical ranges +---------------- +.. autosummary:: + :toctree: generated/ + + arange + linspace + logspace + meshgrid + +.. code:: + + geomspace + mgrid + ogrid + +Building matrices +----------------- +.. autosummary:: + :toctree: generated/ + + tril + +.. code:: + + diag + diagflat + tri + triu + vander + +The Matrix class +---------------- +.. autosummary:: + :toctree: generated/ + +:: + + mat + bmat diff --git a/docs/python_docs/python/tutorials/packages/np/routines.array-manipulation.rst b/docs/python_docs/python/tutorials/packages/np/routines.array-manipulation.rst new file mode 100644 index 000000000000..b43d8f117d02 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.array-manipulation.rst @@ -0,0 +1,143 @@ +Array manipulation routines +*************************** + +.. currentmodule:: mxnet.np + +Basic operations +================ +.. autosummary:: + :toctree: generated/ + +:: + + copyto + +Changing array shape +==================== +.. autosummary:: + :toctree: generated/ + + + reshape + ravel + ndarray.flatten + +:: + + ndarray.flat + +Transpose-like operations +========================= +.. autosummary:: + :toctree: generated/ + + swapaxes + ndarray.T + transpose + moveaxis + +:: + + rollaxis + +Changing number of dimensions +============================= +.. autosummary:: + :toctree: generated/ + + expand_dims + squeeze + broadcast_to + broadcast_arrays + +:: + + atleast_1d + atleast_2d + atleast_3d + broadcast + +Changing kind of array +====================== +.. autosummary:: + :toctree: generated/ + +:: + + asarray + asanyarray + asmatrix + asfarray + asfortranarray + ascontiguousarray + asarray_chkfinite + asscalar + require + +Joining arrays +============== +.. autosummary:: + :toctree: generated/ + + concatenate + stack + dstack + vstack + +:: + + column_stack + hstack + block + +Splitting arrays +================ +.. autosummary:: + :toctree: generated/ + + split + hsplit + vsplit + +:: + + array_split + dsplit + +Tiling arrays +============= +.. autosummary:: + :toctree: generated/ + + tile + repeat + +Adding and removing elements +============================ +.. autosummary:: + :toctree: generated/ + + unique + +:: + + delete + insert + append + resize + trim_zeros + +Rearranging elements +==================== +.. autosummary:: + :toctree: generated/ + + reshape + flip + roll + rot90 + +:: + + fliplr + flipud diff --git a/docs/python_docs/python/tutorials/packages/np/routines.io.rst b/docs/python_docs/python/tutorials/packages/np/routines.io.rst new file mode 100644 index 000000000000..07e487c6eed6 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.io.rst @@ -0,0 +1,114 @@ +Input and output +**************** + +.. currentmodule:: mxnet.np + +NumPy binary files (NPY, NPZ) +----------------------------- +.. autosummary:: + :toctree: generated/ + +:: + load + save + savez + savez_compressed + +The format of these binary file types is documented in +:py:mod:`numpy.lib.format` + +Text files +---------- +.. autosummary:: + :toctree: generated/ + + genfromtxt + +:: + + loadtxt + savetxt + fromregex + fromstring + ndarray.tofile + ndarray.tolist + +Raw binary files +---------------- + +.. autosummary:: + + +:: + + fromfile + ndarray.tofile + +String formatting +----------------- +.. autosummary:: + :toctree: generated/ + + +:: + + array2string + array_repr + array_str + format_float_positional + format_float_scientific + +Memory mapping files +-------------------- +.. autosummary:: + :toctree: generated/ + + +:: + + memmap + +Text formatting options +----------------------- +.. autosummary:: + :toctree: generated/ + + +:: + + set_printoptions + get_printoptions + set_string_function + printoptions + +Base-n representations +---------------------- +.. autosummary:: + :toctree: generated/ + + +:: + + binary_repr + base_repr + +Data sources +------------ +.. autosummary:: + :toctree: generated/ + + +:: + + DataSource + +Binary Format Description +------------------------- +.. autosummary:: + :template: autosummary/minimal_module.rst + :toctree: generated/ + + +:: + + lib.format diff --git a/docs/python_docs/python/tutorials/packages/np/routines.linalg.rst b/docs/python_docs/python/tutorials/packages/np/routines.linalg.rst new file mode 100644 index 000000000000..073dd0b05be5 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.linalg.rst @@ -0,0 +1,106 @@ +.. _routines.linalg: + +.. module:: mxnet.np.linalg + +Linear algebra (:mod:`numpy.linalg`) +************************************ + +The NumPy linear algebra functions rely on BLAS and LAPACK to provide efficient +low level implementations of standard linear algebra algorithms. Those +libraries may be provided by NumPy itself using C versions of a subset of their +reference implementations but, when possible, highly optimized libraries that +take advantage of specialized processor functionality are preferred. Examples +of such libraries are OpenBLAS_, MKL (TM), and ATLAS. Because those libraries +are multithreaded and processor dependent, environmental variables and external +packages such as threadpoolctl_ may be needed to control the number of threads +or specify the processor architecture. + +.. _OpenBLAS: https://www.openblas.net/ +.. _threadpoolctl: https://github.com/joblib/threadpoolctl + +.. currentmodule:: mxnet.np + +Matrix and vector products +-------------------------- +.. autosummary:: + :toctree: generated/ + + dot + vdot + inner + outer + tensordot + einsum + +:: + + linalg.multi_dot + matmul + einsum_path + linalg.matrix_power + kron + +Decompositions +-------------- +.. autosummary:: + :toctree: generated/ + + linalg.svd + +:: + + linalg.cholesky + linalg.qr + +Matrix eigenvalues +------------------ +.. autosummary:: + :toctree: generated/ + + +:: + + linalg.eig + linalg.eigh + linalg.eigvals + linalg.eigvalsh + +Norms and other numbers +----------------------- +.. autosummary:: + :toctree: generated/ + + linalg.norm + trace + +:: + + linalg.cond + linalg.det + linalg.matrix_rank + linalg.slogdet + +Solving equations and inverting matrices +---------------------------------------- +.. autosummary:: + :toctree: generated/ + + +:: + + linalg.solve + linalg.tensorsolve + linalg.lstsq + linalg.inv + linalg.pinv + linalg.tensorinv + +Exceptions +---------- +.. autosummary:: + :toctree: generated/ + + +:: + + linalg.LinAlgError diff --git a/docs/python_docs/python/tutorials/packages/np/routines.math.rst b/docs/python_docs/python/tutorials/packages/np/routines.math.rst new file mode 100644 index 000000000000..6dd85cdbbcab --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.math.rst @@ -0,0 +1,213 @@ +Mathematical functions +********************** + +.. currentmodule:: mxnet.np + +.. note:: + + Currently, most of the math functions only support inputs and outputs of the same dtype. + This limitation usually results in imprecise outputs for ndarrays with integral dtype + while floating-point values are expected in the output. + Appropriate handling of ndarrays integral dtypes is in active development. + + +Trigonometric functions +----------------------- +.. autosummary:: + :toctree: generated/ + + sin + cos + tan + arcsin + arccos + arctan + degrees + radians + hypot + arctan2 + deg2rad + rad2deg + +:: + + unwrap + +Hyperbolic functions +-------------------- +.. autosummary:: + :toctree: generated/ + + sinh + cosh + tanh + arcsinh + arccosh + arctanh + +Rounding +-------- +.. autosummary:: + :toctree: generated/ + + rint + fix + floor + ceil + trunc + around + +:: + + round_ + + +Sums, products, differences +--------------------------- +.. autosummary:: + :toctree: generated/ + + sum + prod + cumsum + +:: + + nanprod + nansum + cumprod + nancumprod + nancumsum + diff + ediff1d + gradient + cross + trapz + +Exponents and logarithms +------------------------ +.. autosummary:: + :toctree: generated/ + + exp + expm1 + log + log10 + log2 + log1p + +:: + + exp2 + logaddexp + logaddexp2 + +Other special functions +----------------------- +.. autosummary:: + :toctree: generated/ + + +:: + + i0 + sinc + +Floating point routines +----------------------- +.. autosummary:: + :toctree: generated/ + + ldexp + +:: + + signbit + copysign + frexp + nextafter + spacing + +Rational routines +----------------- +.. autosummary:: + :toctree: generated/ + + lcm + +:: + + gcd + +Arithmetic operations +--------------------- +.. autosummary:: + :toctree: generated/ + + add + reciprocal + negative + divide + power + subtract + mod + multiply + true_divide + remainder + +:: + + positive + floor_divide + float_power + + fmod + modf + divmod + +Handling complex numbers +------------------------ +.. autosummary:: + :toctree: generated/ + + +:: + + angle + real + imag + conj + conjugate + + +Miscellaneous +------------- +.. autosummary:: + :toctree: generated/ + + clip + + sqrt + cbrt + square + + absolute + sign + maximum + minimum + +:: + + convolve + + fabs + + heaviside + + fmax + fmin + + nan_to_num + real_if_close + + interp diff --git a/docs/python_docs/python/tutorials/packages/np/routines.rst b/docs/python_docs/python/tutorials/packages/np/routines.rst new file mode 100644 index 000000000000..e35d6214d171 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.rst @@ -0,0 +1,47 @@ +Routines +============ + +In this chapter routine docstrings are presented, grouped by functionality. +Many docstrings contain example code, which demonstrates basic usage +of the routine. The examples assume that the `np` module is imported with:: + + >>> from mxnet import np, npx + >>> npx.set_np() + +A convenient way to execute examples is the ``%doctest_mode`` mode of +IPython, which allows for pasting of multi-line examples and preserves +indentation. + +.. toctree:: + :maxdepth: 2 + + routines.array-creation + routines.array-manipulation + routines.bitwise + routines.char + routines.ctypeslib + routines.datetime + routines.dtype + routines.dual + routines.emath + routines.err + routines.fft + routines.financial + routines.functional + routines.help + routines.indexing + routines.io + routines.linalg + routines.logic + routines.ma + routines.math + routines.matlib + routines.other + routines.padding + routines.polynomials + random/index + routines.set + routines.sort + routines.statistics + routines.testing + routines.window diff --git a/docs/python_docs/python/tutorials/packages/np/routines.sort.rst b/docs/python_docs/python/tutorials/packages/np/routines.sort.rst new file mode 100644 index 000000000000..0ae1e92a42b4 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.sort.rst @@ -0,0 +1,49 @@ +Sorting, searching, and counting +================================ + +.. currentmodule:: mxnet.np + +Sorting +------- +.. autosummary:: + :toctree: generated/ + +:: + + ndarray.sort + sort + lexsort + argsort + msort + sort_complex + partition + argpartition + +Searching +--------- +.. autosummary:: + :toctree: generated/ + + argmax + argmin + +:: + + nanargmax + nanargmin + argwhere + nonzero + flatnonzero + where + searchsorted + extract + +Counting +-------- +.. autosummary:: + :toctree: generated/ + + +:: + + count_nonzero diff --git a/docs/python_docs/python/tutorials/packages/np/routines.statistics.rst b/docs/python_docs/python/tutorials/packages/np/routines.statistics.rst new file mode 100644 index 000000000000..e9caf40d2ec1 --- /dev/null +++ b/docs/python_docs/python/tutorials/packages/np/routines.statistics.rst @@ -0,0 +1,74 @@ +Statistics +========== + +.. currentmodule:: mxnet.np + + +Order statistics +---------------- + +.. autosummary:: + :toctree: generated/ + + min + max + +:: + + amin + amax + nanmin + nanmax + ptp + percentile + nanpercentile + quantile + nanquantile + +Averages and variances +---------------------- + +.. autosummary:: + :toctree: generated/ + + mean + std + var + +:: + + median + average + nanmedian + nanmean + nanstd + nanvar + +Correlating +----------- + +.. autosummary:: + :toctree: generated/ + + +:: + + corrcoef + correlate + cov + +Histograms +---------- + +.. autosummary:: + :toctree: generated/ + + histogram + +:: + + histogram2d + histogramdd + bincount + histogram_bin_edges + digitize diff --git a/docs/python_docs/themes/mx-theme/mxtheme/layout.html b/docs/python_docs/themes/mx-theme/mxtheme/layout.html index 994da38fa29e..1e94b28f8fd5 100644 --- a/docs/python_docs/themes/mx-theme/mxtheme/layout.html +++ b/docs/python_docs/themes/mx-theme/mxtheme/layout.html @@ -67,10 +67,12 @@ '_static/feedback.css', ] %} - {%- block header %} - - - {% endblock %} +{% set script_files = script_files + [ + '_static/sphinx_materialdesign_theme.js' + ] +%} + +{%- block header %}{% endblock %} {%- block relbar1 %}{% endblock %} {%- block relbar2 %}{% include "relations.html" %}{% endblock %} {%- block sidebar2 %}{% endblock %} diff --git a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css index cb26a387dd34..9b5a2312e6a6 100644 --- a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css +++ b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css @@ -1,2 +1,2 @@ -.admonition,.mdl-shadow--2dp,.page-content pre:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-data-table,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr:hover{background-color:#eee}.mdl-data-table td,.mdl-data-table th,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{padding:0 18px 12px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td:first-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td:last-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th:last-of-type{padding-right:24px}.mdl-data-table td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td{position:relative;vertical-align:middle;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding-top:12px;box-sizing:border-box}.mdl-data-table td .mdl-data-table__select,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-size:14px;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:before{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;font-feature-settings:"liga";-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:hover:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{text-align:left}.mdl-mini-footer{display:flex;flex-flow:row wrap;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:"";display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul{display:flex;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-card{display:flex;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:#ff6e40;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{align-items:center;color:#000;display:block;display:flex;justify-content:stretch;line-height:normal;padding:16px;perspective-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{align-self:flex-end;color:inherit;display:block;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__supporting-text.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-button{background:transparent;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:hsla(0,0%,62%,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:hsla(0,0%,62%,.4)}.mdl-button.mdl-button--colored{color:#2196f3}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type=submit]{-webkit-appearance:none}.mdl-button--raised{background:hsla(0,0%,62%,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:hsla(0,0%,62%,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:hsla(0,0%,62%,.4)}.mdl-button--raised.mdl-button--colored{background:#2196f3;color:#fff}.mdl-button--raised.mdl-button--colored:active,.mdl-button--raised.mdl-button--colored:focus:not(:active),.mdl-button--raised.mdl-button--colored:hover{background-color:#2196f3}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:hsla(0,0%,62%,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.admonition.attention .mdl-button--fab .admonition-title:before,.admonition.caution .mdl-button--fab .admonition-title:before,.admonition.danger .mdl-button--fab .admonition-title:before,.admonition.error .mdl-button--fab .admonition-title:before,.admonition.hint .mdl-button--fab .admonition-title:before,.admonition.important .mdl-button--fab .admonition-title:before,.admonition.note .mdl-button--fab .admonition-title:before,.admonition.seealso .mdl-button--fab .admonition-title:before,.admonition.tip .mdl-button--fab .admonition-title:before,.admonition.warning .mdl-button--fab .admonition-title:before,.mdl-button--fab .admonition.attention .admonition-title:before,.mdl-button--fab .admonition.caution .admonition-title:before,.mdl-button--fab .admonition.danger .admonition-title:before,.mdl-button--fab .admonition.error .admonition-title:before,.mdl-button--fab .admonition.hint .admonition-title:before,.mdl-button--fab .admonition.important .admonition-title:before,.mdl-button--fab .admonition.note .admonition-title:before,.mdl-button--fab .admonition.seealso .admonition-title:before,.mdl-button--fab .admonition.tip .admonition-title:before,.mdl-button--fab .admonition.warning .admonition-title:before,.mdl-button--fab .material-icons,.mdl-button--fab a.download:before{position:absolute;top:50%;left:50%;transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:hsla(0,0%,62%,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:hsla(0,0%,62%,.4)}.mdl-button--fab.mdl-button--colored{background:#ff6e40;color:#fff}.mdl-button--fab.mdl-button--colored:active,.mdl-button--fab.mdl-button--colored:focus:not(:active),.mdl-button--fab.mdl-button--colored:hover{background-color:#ff6e40}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.admonition.attention .mdl-button--icon .admonition-title:before,.admonition.caution .mdl-button--icon .admonition-title:before,.admonition.danger .mdl-button--icon .admonition-title:before,.admonition.error .mdl-button--icon .admonition-title:before,.admonition.hint .mdl-button--icon .admonition-title:before,.admonition.important .mdl-button--icon .admonition-title:before,.admonition.note .mdl-button--icon .admonition-title:before,.admonition.seealso .mdl-button--icon .admonition-title:before,.admonition.tip .mdl-button--icon .admonition-title:before,.admonition.warning .mdl-button--icon .admonition-title:before,.mdl-button--icon .admonition.attention .admonition-title:before,.mdl-button--icon .admonition.caution .admonition-title:before,.mdl-button--icon .admonition.danger .admonition-title:before,.mdl-button--icon .admonition.error .admonition-title:before,.mdl-button--icon .admonition.hint .admonition-title:before,.mdl-button--icon .admonition.important .admonition-title:before,.mdl-button--icon .admonition.note .admonition-title:before,.mdl-button--icon .admonition.seealso .admonition-title:before,.mdl-button--icon .admonition.tip .admonition-title:before,.mdl-button--icon .admonition.warning .admonition-title:before,.mdl-button--icon .material-icons,.mdl-button--icon a.download:before{position:absolute;top:50%;left:50%;transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.admonition.attention .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.caution .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.danger .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.error .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.hint .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.important .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.note .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.seealso .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.tip .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.warning .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.attention .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.caution .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.danger .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.error .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.hint .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.important .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.note .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.seealso .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.tip .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.warning .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .material-icons,.mdl-button--icon.mdl-button--mini-icon a.download:before{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple,.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:#2196f3}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:#fff}.mdl-button--primary.mdl-button--primary.mdl-button--fab,.mdl-button--primary.mdl-button--primary.mdl-button--raised{color:#fff;background-color:#2196f3}.mdl-button--accent.mdl-button--accent{color:#ff6e40}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:#fff}.mdl-button--accent.mdl-button--accent.mdl-button--fab,.mdl-button--accent.mdl-button--accent.mdl-button--raised{color:#fff;background-color:#ff6e40}.mdl-button.mdl-button--disabled.mdl-button--disabled,.mdl-button[disabled][disabled]{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab.mdl-button--disabled.mdl-button--disabled,.mdl-button--fab[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised.mdl-button--disabled.mdl-button--disabled,.mdl-button--raised[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored.mdl-button--disabled.mdl-button--disabled,.mdl-button--colored[disabled][disabled]{color:rgba(0,0,0,.26)}.admonition.attention .mdl-button .admonition-title:before,.admonition.caution .mdl-button .admonition-title:before,.admonition.danger .mdl-button .admonition-title:before,.admonition.error .mdl-button .admonition-title:before,.admonition.hint .mdl-button .admonition-title:before,.admonition.important .mdl-button .admonition-title:before,.admonition.note .mdl-button .admonition-title:before,.admonition.seealso .mdl-button .admonition-title:before,.admonition.tip .mdl-button .admonition-title:before,.admonition.warning .mdl-button .admonition-title:before,.mdl-button .admonition.attention .admonition-title:before,.mdl-button .admonition.caution .admonition-title:before,.mdl-button .admonition.danger .admonition-title:before,.mdl-button .admonition.error .admonition-title:before,.mdl-button .admonition.hint .admonition-title:before,.mdl-button .admonition.important .admonition-title:before,.mdl-button .admonition.note .admonition-title:before,.mdl-button .admonition.seealso .admonition-title:before,.mdl-button .admonition.tip .admonition-title:before,.mdl-button .admonition.warning .admonition-title:before,.mdl-button .material-icons,.mdl-button a.download:before{vertical-align:middle}.font-light{font-weight:300}.font-regular{font-weight:400}.font-heavy{font-weight:700}.left{text-align:left}.right{text-align:right}.center{text-align:center;margin-left:auto;margin-right:auto}.justify{text-align:justify}.hidden-sm{display:none}.container{width:100%;margin-left:auto;margin-right:auto}@media only screen and (min-width:33.75em){.container{width:80%}}@media only screen and (min-width:60em){.container{width:75%;max-width:60rem}}.row{position:relative;width:100%}.row [class^=col]{float:left;margin:.5rem 1%;min-height:.125rem}.row:after{content:"";display:table;clear:both}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12{width:98%}.col-1-sm{width:6.33333%}.col-2-sm{width:14.66667%}.col-3-sm{width:23%}.col-4-sm{width:31.33333%}.col-5-sm{width:39.66667%}.col-6-sm{width:48%}.col-7-sm{width:56.33333%}.col-8-sm{width:64.66667%}.col-9-sm{width:73%}.col-10-sm{width:81.33333%}.col-11-sm{width:89.66667%}.col-12-sm{width:98%}@media only screen and (min-width:45em){.col-1{width:6.33333%}.col-2{width:14.66667%}.col-3{width:23%}.col-4{width:31.33333%}.col-5{width:39.66667%}.col-6{width:48%}.col-7{width:56.33333%}.col-8{width:64.66667%}.col-9{width:73%}.col-10{width:81.33333%}.col-11{width:89.66667%}.col-12{width:98%}.hidden-sm{display:block}}.row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;flex-wrap:wrap}.row>[class*=col-]{display:flex;flex-direction:column}.admonition.attention .admonition-title:before,.admonition.caution .admonition-title:before,.admonition.danger .admonition-title:before,.admonition.error .admonition-title:before,.admonition.hint .admonition-title:before,.admonition.important .admonition-title:before,.admonition.note .admonition-title:before,.admonition.seealso .admonition-title:before,.admonition.tip .admonition-title:before,.admonition.warning .admonition-title:before,.material-icons,a.download:before{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}html{font-size:16px}body{display:block!important;background-color:#fafafa;font-size:1rem;line-height:1.5rem;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}.mdl-layout__content:focus{outline:none}a.download>code.download,blockquote,h1,h2,h3,h4,h5,h6,span.mdl-layout-title{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}.contents,.contents a,.globaltoc a.current,.toc-backref,.toctree-wrapper,.toctree-wrapper a,h1,h2,h3,h4,h5,h6{color:#048ccc!important}a{text-decoration:none}.page-content,.page-content dd,.page-content dl,.page-content dt,.page-content ol,.page-content p,.page-content table,.page-content td,.page-content th,.page-content ul{font-size:1rem}.brand{color:inherit;text-decoration:none}.section{overflow-x:auto}img{max-width:100%;display:block;margin-left:auto;margin-right:auto}div.figure p.caption{text-align:center;margin-top:.75rem}div.figure p.caption span.caption-number{font-style:normal}div.figure p.caption .caption-number:after{content:"\00a0"}.svg-icon{width:16px;height:16px;display:inline-block;fill:#f5f5f5;padding-right:5px;padding-top:4px;vertical-align:text-top}.admonition.attention a.download>i.admonition-title:before,.admonition.caution a.download>i.admonition-title:before,.admonition.danger a.download>i.admonition-title:before,.admonition.error a.download>i.admonition-title:before,.admonition.hint a.download>i.admonition-title:before,.admonition.important a.download>i.admonition-title:before,.admonition.note a.download>i.admonition-title:before,.admonition.seealso a.download>i.admonition-title:before,.admonition.tip a.download>i.admonition-title:before,.admonition.warning a.download>i.admonition-title:before,a.download>i.material-icons{position:relative;top:5px}a.download{text-decoration:none}.wrapper:after{content:"";display:table;clear:both}.wrapper{max-width:1090px;margin-right:auto;margin-left:auto;padding-right:45px;padding-left:30px}@media screen and (max-width:1024px){.wrapper{max-width:1120px;padding-right:15px;padding-left:15px}}.mdl-layout{margin-top:76px}.document{width:100%;margin:0 auto;display:flex}@media (min-width:1795px){.document{width:1400px}}.document .page-content{width:100%;margin:0 auto;padding:0 12px}@media (min-width:992px){.document .page-content{width:90%;padding:0 5%}}@media (min-width:1200px){.document .page-content{width:calc(90% - 230px);padding:0 5%}}.document .side-doc-outline{width:230px}@media (max-width:1199px){.document .side-doc-outline{display:none}}.document .side-doc-outline--content{position:fixed;overflow-x:auto;overflow-y:auto;width:inherit}.document .side-doc-outline--content::-webkit-scrollbar{width:6px}.document .side-doc-outline--content::-webkit-scrollbar-track{border-radius:6px}.document .side-doc-outline--content::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:6px;box-shadow:0 0 0 1px hsla(0,0%,100%,.3)}@keyframes float-in{0%{transform:translateY(.5rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes float-out{0%{transform:translateY(0);opacity:1}to{transform:translateY(.5rem);opacity:0}}.page-content .headerlink{display:inline-block;text-decoration:none;margin-left:.8rem;color:inherit;opacity:0}.page-content .headerlink:hover{animation:float-in .2s cubic-bezier(.4,0,.2,1) 0s forwards}.page-content h1 .toc-backref,.page-content h2 .toc-backref,.page-content h3 .toc-backref,.page-content h4 .toc-backref,.page-content h5 .toc-backref,.page-content h6 .toc-backref{text-decoration:none}.page-content h1:hover .headerlink,.page-content h2:hover .headerlink,.page-content h3:hover .headerlink,.page-content h4:hover .headerlink,.page-content h5:hover .headerlink,.page-content h6:hover .headerlink{animation:float-in .2s cubic-bezier(.4,0,.2,1) 0s forwards}.page-content h1{font-size:2rem;line-height:2.25rem}.page-content h2{font-size:1.75rem;line-height:2rem;padding-top:1.5rem;margin-top:0;margin-bottom:1rem}.page-content h3{font-size:1.5rem;line-height:1.75rem;padding-top:1rem;margin-top:0;margin-bottom:.75rem}.page-content h4{font-size:1.25rem;line-height:1.5rem;padding-top:.75rem;margin-top:0;margin-bottom:.5rem}.page-content div.page-content h5{font-size:1.1rem;line-height:1.5rem;padding-top:2rem;margin-top:0;margin-bottom:1rem}.page-content div.page-content h6{font-size:1rem;line-height:1.5rem;padding-top:2rem;margin-top:0;margin-bottom:1rem}.admonition{padding:12px 20px;margin-top:10px;margin-bottom:10px}.admonition p.last{margin:16px}.admonition .admonition-title{font-size:16px;font-weight:700;color:#555;text-transform:uppercase;margin-top:7px}.admonition.note{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.note .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.note .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"info_outline";font-size:18px}.admonition.seealso{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.seealso .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.seealso .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"search";font-size:18px}.admonition.hint{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.hint .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.hint .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"help_outline";font-size:18px}.admonition.warning{border-left:4px solid #ffc107;background-color:rgba(255,193,7,.1)}.admonition.warning .admonition-title{font-size:16px;font-weight:700;color:#ffc107;margin-top:4px;margin-bottom:8px}.admonition.warning .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"warning";font-size:18px}.admonition.attention{border-left:4px solid #ffc107;background-color:rgba(255,193,7,.1)}.admonition.attention .admonition-title{font-size:16px;font-weight:700;color:#ffc107;margin-top:4px;margin-bottom:8px}.admonition.attention .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"warning";font-size:18px}.admonition.tip{border-left:4px solid #8bc34a;background-color:rgba(139,195,74,.1)}.admonition.tip .admonition-title{font-size:16px;font-weight:700;color:#8bc34a;margin-top:4px;margin-bottom:8px}.admonition.tip .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"lightbulb_outline";font-size:18px}.admonition.important{border-left:4px solid #8bc34a;background-color:rgba(139,195,74,.1)}.admonition.important .admonition-title{font-size:16px;font-weight:700;color:#8bc34a;margin-top:4px;margin-bottom:8px}.admonition.important .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"check_circle";font-size:18px}.admonition.error{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.error .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.error .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.admonition.caution{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.caution .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.caution .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.admonition.danger{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.danger .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.danger .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.page-content .highlight{margin:1px 0}.page-content .highlight pre{background:rgba(0,0,0,.05);color:rgba(0,0,0,.87);font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace;padding:.75rem;overflow:auto;overflow-y:hidden}.page-content .highlight pre .nd,.page-content .highlight pre .o{color:rgba(0,0,0,.87)}.page-content div.highlight-console div.highlight{background:none}.page-content .output .highlight pre{color:rgba(0,0,0,.87);background:#fafafa;border:1px solid #999;padding:.75rem}.page-content .code,.page-content code:not(.download){margin:0;border-radius:2px}.page-content .code,.page-content .code span.pre,.page-content code:not(.download),.page-content code:not(.download) span.pre{font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace}.page-content .viewcode-link{padding-left:2em;font-size:80%}.page-content .class>dt,.page-content .function>dt,.page-content .method>dt,.page-content .rubric{display:table;margin:10px 0;font-size:100%;line-height:normal;background:#e7f2fa;color:#2b98f0;border-top:3px solid #55adf3;padding:10px;position:relative}.page-content .class>dt .descclassname,.page-content .class>dt .descname,.page-content .function>dt .descclassname,.page-content .function>dt .descname,.page-content .method>dt .descclassname,.page-content .method>dt .descname,.page-content .rubric .descclassname,.page-content .rubric .descname{color:rgba(0,0,0,.87);background:#e7f2fa;padding:3px}.page-content .class>dt em,.page-content .function>dt em,.page-content .method>dt em,.page-content .rubric em{padding:0 2px}.page-content .rubric{margin:30px 0 10px}.page-content .field-body{padding-left:40px}.page-content .field-body ul{padding:0 0 0 16px;margin:0}.page-content .seealso .docutils>dt{float:left;clear:left;padding:0 6px}.page-content .seealso .docutils>dd{padding-left:6em}.page-content .nblast{padding-bottom:1em}.page-content pre{font-size:90%;background:#eee;color:#455a64;padding:16px 32px;width:auto;border-radius:4px;word-wrap:break-word}.page-content pre:hover:before{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;padding:0 .5rem;content:attr(click-to-copy);color:rgba(0,0,0,.5);border-radius:4px;position:relative;float:right;top:-.5rem;right:-.5rem;background:#c8c8c8;font-size:.8rem;cursor:pointer}.page-content blockquote{font-size:1rem;padding:0 1rem;border-left:3px solid rgba(0,0,0,.05)}.page-content blockquote:after{content:""!important;margin-left:0}.page-content blockquote:before{content:""!important}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){margin:1.5rem 0;table-layout:fixed;max-width:100%;min-width:70%}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{white-space:normal;overflow-wrap:break-word}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption{font-size:16px;margin:1rem 0 .8rem;white-space:normal}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption .caption-number{font-style:normal}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption .caption-number:after{content:"\00a0"}.globaltoc .caption,.globaltoc .toc{display:none}.globaltoc ul{list-style-type:none;padding:0;margin:0}.globaltoc ul li{min-height:18px}.globaltoc ul li .link-wrapper{display:flex;justify-content:space-between}.globaltoc ul li .link-wrapper>a{padding:4px 0;display:block;width:100%;font-size:1rem;text-decoration:none;color:#757575}.globaltoc ul li .link-wrapper>a.current{font-weight:700}.globaltoc .nav-toggle{padding:0;float:right;display:flex;align-items:center;justify-content:center;height:36px}.globaltoc .nav-toggle>a{padding:0;margin-left:0;margin-right:4px;cursor:pointer}.globaltoc .nav-toggle>a>i{font-size:18px}.globaltoc .nav-toggle.show{transform:rotate(180deg)}.globaltoc .nav-toggle.show>a{margin-right:0;margin-left:4px}.globaltoc nav>ul>li>span.link-wrapper{padding-left:8px}.globaltoc nav>ul>li>ul>li>span.link-wrapper{padding-left:16px}.globaltoc nav>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:24px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:32px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:40px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:48px}.localtoc{font-size:.75rem;padding-top:1rem}.localtoc .caption{padding-left:12px}.localtoc .caption-text{font-size:.9rem;font-weight:700}.localtoc>ul>li>a{display:none}.localtoc ul{padding:0;list-style-type:none}.localtoc li{padding-left:6px}.localtoc a{display:block;text-decoration:none;color:inherit;margin-top:8px;padding-left:8px;line-height:1.1rem}.localtoc a.current{padding-left:5px;border-left:3px solid;font-weight:700}.contents.topic,.toctree-wrapper{border-left:5px solid}.contents.topic>p.topic-title,.toctree-wrapper>p.caption{color:#757575;font-size:1rem;padding-left:14px}.contents.topic ul,.toctree-wrapper ul{padding-left:14px;list-style:none;line-height:30px}.contents.topic a,.toctree-wrapper a{font-size:1.2rem;text-decoration:none}.contents.topic a .pre,.toctree-wrapper a .pre{font-size:1rem}.contents.topic>ul>li>a,.toctree-wrapper>ul>li>a{font-size:1.3rem}.contents.topic>ul>li>a .pre,.toctree-wrapper>ul>li>a .pre{font-size:1.1rem}.page-content ul li{margin:.3rem 0}.page-content ul li p{margin:0}.page-content .option-list .option{font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace}.page-content .option-list td{padding:.5rem;border:none}.mdl-layout__drawer{background-color:#fff}.mdl-layout__drawer::-webkit-scrollbar{width:6px}.mdl-layout__drawer::-webkit-scrollbar-track{border-radius:6px}.mdl-layout__drawer::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:6px;box-shadow:0 0 0 1px hsla(0,0%,100%,.3)}.mdl-layout__drawer>.mdl-layout-title{font-weight:700;text-align:right;margin:0;padding:0;line-height:32px;border-bottom:1px solid rgba(0,0,0,.1);min-height:64px}.mdl-layout__drawer>.mdl-layout-title .title{color:inherit;display:block;height:100%;width:100%;text-decoration:none}.mdl-layout__drawer>.mdl-layout-title .title>img.logo{width:100%;margin:0;padding:0}.mdl-layout__drawer>.mdl-layout-title .title-text{font-weight:700;text-align:right;padding:0 10px;margin:16px 0 8px;line-height:32px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;color:inherit;display:block}nav.breadcrumb>a.mdl-navigation__link{padding:0 8px;font-size:18px}@media (max-width:1199px){nav.breadcrumb{width:calc(100% - 64px)}nav.breadcrumb a.mdl-navigation__link.is-active{overflow-x:hidden;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.admonition.attention nav.breadcrumb i.admonition-title:before,.admonition.caution nav.breadcrumb i.admonition-title:before,.admonition.danger nav.breadcrumb i.admonition-title:before,.admonition.error nav.breadcrumb i.admonition-title:before,.admonition.hint nav.breadcrumb i.admonition-title:before,.admonition.important nav.breadcrumb i.admonition-title:before,.admonition.note nav.breadcrumb i.admonition-title:before,.admonition.seealso nav.breadcrumb i.admonition-title:before,.admonition.tip nav.breadcrumb i.admonition-title:before,.admonition.warning nav.breadcrumb i.admonition-title:before,nav.breadcrumb .admonition.attention i.admonition-title:before,nav.breadcrumb .admonition.caution i.admonition-title:before,nav.breadcrumb .admonition.danger i.admonition-title:before,nav.breadcrumb .admonition.error i.admonition-title:before,nav.breadcrumb .admonition.hint i.admonition-title:before,nav.breadcrumb .admonition.important i.admonition-title:before,nav.breadcrumb .admonition.note i.admonition-title:before,nav.breadcrumb .admonition.seealso i.admonition-title:before,nav.breadcrumb .admonition.tip i.admonition-title:before,nav.breadcrumb .admonition.warning i.admonition-title:before,nav.breadcrumb a.mdl-navigation__link:not(.is-active),nav.breadcrumb i.material-icons{display:none}}div.mdl-layout__header{margin-top:77px}.mdl-layout__drawer-button{top:13px!important}div.mdl-layout__header-row.header-links{background:hsla(0,0%,100%,.2);width:100%;overflow-x:auto;overflow-y:hidden}div.mdl-layout__header-row.header-links a.mdl-navigation__link{font-size:1rem}div.mdl-layout__header-row.header-links a.mdl-navigation__link i{font-size:1.2rem;margin:0 8px;position:relative;bottom:-.1rem}div.mdl-layout__header-row.header-links a.mdl-navigation__link:hover{background-color:#2196f3;color:#eee}div.mdl-layout__header-row.header-links a.mdl-navigation__link[href="#"]{background-color:#2196f3;opacity:1;color:#fff}.site-title{font-weight:300!important;line-height:57px;letter-spacing:-1px;margin-bottom:0;float:left;color:#fff}.site-title,.site-title:visited{color:#424242}.site-header{position:fixed;top:0;width:100%;min-height:55px;padding-top:10px;padding-bottom:10px;background-color:#048ccc;z-index:10;font-weight:300;font-size:17px;border-bottom:1px solid #fff}.site-header-logo{width:120px;display:initial}.site-nav{float:right;line-height:57px}.site-nav .menu-icon,.site-nav .nav-trigger{display:none}.site-nav .page-link{color:#fff;line-height:1.5;font-weight:300}.site-nav .page-link:not(:last-child){margin-right:40px}.site-nav .page-link:hover{color:#fff;text-shadow:-.06ex 0 #fff,.06ex 0 #fff}.site-nav .page-link.page-current{color:#fff;text-decoration:underline}@media screen and (max-width:1024px){.site-nav{position:absolute;top:9px;right:15px;background-color:#178dc9;border-radius:2px;text-align:right}.site-nav label[for=nav-trigger]{display:block;float:right;width:36px;height:36px;z-index:2;cursor:pointer}.site-nav .menu-icon{display:block;float:right;width:36px;height:26px;line-height:0;padding-top:20px;text-align:center}.site-nav .menu-icon>svg{fill:#fff}.site-nav input~.trigger{clear:both;display:none}.site-nav input:checked~.trigger{display:block;padding-bottom:5px}.site-nav .page-link{padding:5px 10px;display:block;margin-left:20px}.site-nav .page-link:not(:last-child){margin-right:0}}footer.mdl-mini-footer{background-color:#212121}footer.mdl-mini-footer>div.mdl-mini-footer__left-section{margin-bottom:20px;display:flex;flex-direction:column}footer.mdl-mini-footer>div.mdl-mini-footer__left-section .mdl-logo{font-size:1.1rem}footer.mdl-mini-footer>div.mdl-mini-footer__right-section{font-size:.9rem;display:flex;flex-direction:column;justify-content:flex-end}footer.mdl-mini-footer>div.mdl-mini-footer__right-section a{color:inherit;font-weight:700;text-decoration:none}footer.mdl-mini-footer p.caption{display:none}.pagenation{width:100%;margin-top:80px;height:92px;background-color:#424242;display:flex}.pagenation #button-next,.pagenation #button-prev,.pagenation .button-common{text-transform:none;padding:0;height:92px;display:flex;justify-content:center;align-items:center;color:#fff}.pagenation #button-prev{margin-right:auto}.pagenation #button-prev .pagenation-text{text-align:left}.pagenation #button-next{margin-left:auto;flex-direction:row-reverse}.pagenation #button-next .pagenation-text{text-align:right}.pagenation-arrow-L{margin-right:20px}.pagenation-arrow-R{margin-left:20px}.pagenation-text{line-height:30px;font-size:20px}.pagenation-direction{opacity:.7;font-size:18px}@media screen and (max-width:1024px){.pagenation #button-prev{width:20%}.pagenation #button-next{width:80%}.pagenation #button-prev .pagenation-text{display:none}}@media screen and (min-width:1025px){.pagenation #button-next,.pagenation #button-prev{width:50%}.pagenation #button-prev .pagenation-text{display:block}}.site-footer{border-top:1px solid #f5f5f5;padding:30px 0;background-color:#424242}.site-footer .footer-category-title{color:#048ccc}.site-footer a,.site-footer a:visited{color:#f5f5f5!important}.site-footer2{background-color:#424242;padding-top:40px;padding-bottom:10px}.footer-heading{margin-bottom:15px}.contact-list,.social-media-list{list-style:none;margin-left:0}.footer-bottom-warning{font-size:80%;color:#fff;float:left}.footer-logo{width:200px;margin-bottom:30px;margin-top:30px}.footer-col{float:left;margin-bottom:15px;padding-left:15px}.footer-text{color:#f5f5f5}#waterfall-exp::-webkit-input-placeholder{color:#ccc}#waterfall-exp:-ms-input-placeholder{color:#ccc}#waterfall-exp::-moz-placeholder{color:#ccc}ul.search span.highlighted{font-weight:700}ul.search>li{margin-bottom:24px}#search-results ul{list-style:none;padding:0}#search-results ul li>a{text-decoration:none;font-size:1.2rem}a.download:before{content:"file_download";position:relative;top:5px;margin-right:5px}button.download{position:sticky;margin-left:1em}.mdl-card{margin:1em 1.5em 1em 0;display:inline-block;width:250px;min-height:140px;padding:18px}.mdl-card:hover{box-shadow:0 10px 20px rgba(0,0,0,.25),0 6px 6px rgba(0,0,0,.22);color:#000;cursor:pointer}.mdl-card__title{padding:0 0 1em;font-size:18px;color:#444}.mdl-card__supporting-text{line-height:1.5rem;padding:0;width:100%}.head-card.mdl-card{width:auto;display:block;max-width:800px;padding:24px}.head-card>.mdl-card__title{padding-bottom:0;height:60px;font-weight:700;text-transform:uppercase}.head-card>.mdl-card__menu{color:#fff}.head-card>.mdl-card__actions{padding:0}.cards{display:flex;flex-direction:row;flex-wrap:wrap} +.admonition,.mdl-shadow--2dp,.page-content pre:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-shadow--3dp{box-shadow:0 3px 4px 0 rgba(0,0,0,.14),0 3px 3px -2px rgba(0,0,0,.2),0 1px 8px 0 rgba(0,0,0,.12)}.mdl-shadow--4dp{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2)}.mdl-shadow--6dp{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.2)}.mdl-shadow--8dp{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.2)}.mdl-shadow--16dp{box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.2)}.mdl-shadow--24dp{box-shadow:0 9px 46px 8px rgba(0,0,0,.14),0 11px 15px -7px rgba(0,0,0,.12),0 24px 38px 3px rgba(0,0,0,.2)}.mdl-data-table,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){position:relative;border:1px solid rgba(0,0,0,.12);border-collapse:collapse;white-space:nowrap;font-size:13px;background-color:#fff}.mdl-data-table thead,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) thead{padding-bottom:3px}.mdl-data-table thead .mdl-data-table__select,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) thead .mdl-data-table__select{margin-top:0}.mdl-data-table tbody tr,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr{position:relative;height:48px;transition-duration:.28s;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-property:background-color}.mdl-data-table tbody tr.is-selected,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr.is-selected{background-color:#e0e0e0}.mdl-data-table tbody tr:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) tbody tr:hover{background-color:#eee}.mdl-data-table td,.mdl-data-table th,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{padding:0 18px 12px;text-align:right}.mdl-data-table td:first-of-type,.mdl-data-table th:first-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td:first-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th:first-of-type{padding-left:24px}.mdl-data-table td:last-of-type,.mdl-data-table th:last-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td:last-of-type,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th:last-of-type{padding-right:24px}.mdl-data-table td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td{position:relative;vertical-align:middle;height:48px;border-top:1px solid rgba(0,0,0,.12);border-bottom:1px solid rgba(0,0,0,.12);padding-top:12px;box-sizing:border-box}.mdl-data-table td .mdl-data-table__select,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td .mdl-data-table__select{vertical-align:middle}.mdl-data-table th,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{position:relative;vertical-align:bottom;text-overflow:ellipsis;font-size:14px;font-weight:700;line-height:24px;letter-spacing:0;height:48px;font-size:12px;color:rgba(0,0,0,.54);padding-bottom:8px;box-sizing:border-box}.mdl-data-table th.mdl-data-table__header--sorted-ascending,.mdl-data-table th.mdl-data-table__header--sorted-descending,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending{color:rgba(0,0,0,.87)}.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:before{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;word-wrap:normal;font-feature-settings:"liga";-webkit-font-feature-settings:"liga";-webkit-font-smoothing:antialiased;font-size:16px;content:"\e5d8";margin-right:5px;vertical-align:sub}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:hover,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:hover{cursor:pointer}.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-ascending:hover:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:hover:before{color:rgba(0,0,0,.26)}.mdl-data-table th.mdl-data-table__header--sorted-descending:before,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th.mdl-data-table__header--sorted-descending:before{content:"\e5db"}.mdl-data-table__select{width:16px}.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{text-align:left}.mdl-mini-footer{display:flex;flex-flow:row wrap;justify-content:space-between;padding:32px 16px;color:#9e9e9e;background-color:#424242}.mdl-mini-footer:after{content:"";display:block}.mdl-mini-footer .mdl-logo{line-height:36px}.mdl-mini-footer--link-list,.mdl-mini-footer__link-list,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul{display:flex;flex-flow:row nowrap;list-style:none;margin:0;padding:0}.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul li{margin-bottom:0;margin-right:16px}@media screen and (min-width:760px){.mdl-mini-footer--link-list li,.mdl-mini-footer__link-list li,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul li{line-height:36px}}.mdl-mini-footer--link-list a,.mdl-mini-footer__link-list a,footer.mdl-mini-footer>div.mdl-mini-footer__left-section ul a{color:inherit;text-decoration:none;white-space:nowrap}.mdl-mini-footer--left-section,.mdl-mini-footer__left-section{display:inline-block;order:0}.mdl-mini-footer--right-section,.mdl-mini-footer__right-section{display:inline-block;order:1}.mdl-mini-footer--social-btn,.mdl-mini-footer__social-btn{width:36px;height:36px;padding:0;margin:0;background-color:#9e9e9e;border:none}.mdl-card{display:flex;flex-direction:column;font-size:16px;font-weight:400;min-height:200px;overflow:hidden;width:330px;z-index:1;position:relative;background:#fff;border-radius:2px;box-sizing:border-box}.mdl-card__media{background-color:#ff6e40;background-repeat:repeat;background-position:50% 50%;background-size:cover;background-origin:padding-box;background-attachment:scroll;box-sizing:border-box}.mdl-card__title{align-items:center;color:#000;display:block;display:flex;justify-content:stretch;line-height:normal;padding:16px;perspective-origin:165px 56px;transform-origin:165px 56px;box-sizing:border-box}.mdl-card__title.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__title-text{align-self:flex-end;color:inherit;display:block;display:flex;font-size:24px;font-weight:300;line-height:normal;overflow:hidden;transform-origin:149px 48px;margin:0}.mdl-card__subtitle-text{font-size:14px;color:rgba(0,0,0,.54);margin:0}.mdl-card__supporting-text{color:rgba(0,0,0,.54);font-size:1rem;line-height:18px;overflow:hidden;padding:16px;width:90%}.mdl-card__supporting-text.mdl-card--border{border-bottom:1px solid rgba(0,0,0,.1)}.mdl-card__actions{font-size:16px;line-height:normal;width:100%;background-color:transparent;padding:8px;box-sizing:border-box}.mdl-card__actions.mdl-card--border{border-top:1px solid rgba(0,0,0,.1)}.mdl-card--expand{flex-grow:1}.mdl-card__menu{position:absolute;right:16px;top:16px}.mdl-button{background:transparent;border:none;border-radius:2px;color:#000;position:relative;height:36px;margin:0;min-width:64px;padding:0 16px;display:inline-block;font-family:Roboto,Helvetica,Arial,sans-serif;font-size:14px;font-weight:500;text-transform:uppercase;line-height:1;letter-spacing:0;overflow:hidden;will-change:box-shadow;transition:box-shadow .2s cubic-bezier(.4,0,1,1),background-color .2s cubic-bezier(.4,0,.2,1),color .2s cubic-bezier(.4,0,.2,1);outline:none;cursor:pointer;text-decoration:none;text-align:center;line-height:36px;vertical-align:middle}.mdl-button::-moz-focus-inner{border:0}.mdl-button:hover{background-color:hsla(0,0%,62%,.2)}.mdl-button:focus:not(:active){background-color:rgba(0,0,0,.12)}.mdl-button:active{background-color:hsla(0,0%,62%,.4)}.mdl-button.mdl-button--colored{color:#2196f3}.mdl-button.mdl-button--colored:focus:not(:active){background-color:rgba(0,0,0,.12)}input.mdl-button[type=submit]{-webkit-appearance:none}.mdl-button--raised{background:hsla(0,0%,62%,.2);box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.mdl-button--raised:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:hsla(0,0%,62%,.4)}.mdl-button--raised:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:hsla(0,0%,62%,.4)}.mdl-button--raised.mdl-button--colored{background:#2196f3;color:#fff}.mdl-button--raised.mdl-button--colored:active,.mdl-button--raised.mdl-button--colored:focus:not(:active),.mdl-button--raised.mdl-button--colored:hover{background-color:#2196f3}.mdl-button--raised.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--fab{border-radius:50%;font-size:24px;height:56px;margin:auto;min-width:56px;width:56px;padding:0;overflow:hidden;background:hsla(0,0%,62%,.2);box-shadow:0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);position:relative;line-height:normal}.admonition.attention .mdl-button--fab .admonition-title:before,.admonition.caution .mdl-button--fab .admonition-title:before,.admonition.danger .mdl-button--fab .admonition-title:before,.admonition.error .mdl-button--fab .admonition-title:before,.admonition.hint .mdl-button--fab .admonition-title:before,.admonition.important .mdl-button--fab .admonition-title:before,.admonition.note .mdl-button--fab .admonition-title:before,.admonition.seealso .mdl-button--fab .admonition-title:before,.admonition.tip .mdl-button--fab .admonition-title:before,.admonition.warning .mdl-button--fab .admonition-title:before,.mdl-button--fab .admonition.attention .admonition-title:before,.mdl-button--fab .admonition.caution .admonition-title:before,.mdl-button--fab .admonition.danger .admonition-title:before,.mdl-button--fab .admonition.error .admonition-title:before,.mdl-button--fab .admonition.hint .admonition-title:before,.mdl-button--fab .admonition.important .admonition-title:before,.mdl-button--fab .admonition.note .admonition-title:before,.mdl-button--fab .admonition.seealso .admonition-title:before,.mdl-button--fab .admonition.tip .admonition-title:before,.mdl-button--fab .admonition.warning .admonition-title:before,.mdl-button--fab .material-icons,.mdl-button--fab a.download:before{position:absolute;top:50%;left:50%;transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--fab.mdl-button--mini-fab{height:40px;min-width:40px;width:40px}.mdl-button--fab .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button--fab:active{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.2);background-color:hsla(0,0%,62%,.4)}.mdl-button--fab:focus:not(:active){box-shadow:0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);background-color:hsla(0,0%,62%,.4)}.mdl-button--fab.mdl-button--colored{background:#ff6e40;color:#fff}.mdl-button--fab.mdl-button--colored:active,.mdl-button--fab.mdl-button--colored:focus:not(:active),.mdl-button--fab.mdl-button--colored:hover{background-color:#ff6e40}.mdl-button--fab.mdl-button--colored .mdl-ripple{background:#fff}.mdl-button--icon{border-radius:50%;font-size:24px;height:32px;margin-left:0;margin-right:0;min-width:32px;width:32px;padding:0;overflow:hidden;color:inherit;line-height:normal}.admonition.attention .mdl-button--icon .admonition-title:before,.admonition.caution .mdl-button--icon .admonition-title:before,.admonition.danger .mdl-button--icon .admonition-title:before,.admonition.error .mdl-button--icon .admonition-title:before,.admonition.hint .mdl-button--icon .admonition-title:before,.admonition.important .mdl-button--icon .admonition-title:before,.admonition.note .mdl-button--icon .admonition-title:before,.admonition.seealso .mdl-button--icon .admonition-title:before,.admonition.tip .mdl-button--icon .admonition-title:before,.admonition.warning .mdl-button--icon .admonition-title:before,.mdl-button--icon .admonition.attention .admonition-title:before,.mdl-button--icon .admonition.caution .admonition-title:before,.mdl-button--icon .admonition.danger .admonition-title:before,.mdl-button--icon .admonition.error .admonition-title:before,.mdl-button--icon .admonition.hint .admonition-title:before,.mdl-button--icon .admonition.important .admonition-title:before,.mdl-button--icon .admonition.note .admonition-title:before,.mdl-button--icon .admonition.seealso .admonition-title:before,.mdl-button--icon .admonition.tip .admonition-title:before,.mdl-button--icon .admonition.warning .admonition-title:before,.mdl-button--icon .material-icons,.mdl-button--icon a.download:before{position:absolute;top:50%;left:50%;transform:translate(-12px,-12px);line-height:24px;width:24px}.mdl-button--icon.mdl-button--mini-icon{height:24px;min-width:24px;width:24px}.admonition.attention .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.caution .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.danger .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.error .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.hint .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.important .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.note .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.seealso .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.tip .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.admonition.warning .mdl-button--icon.mdl-button--mini-icon .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.attention .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.caution .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.danger .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.error .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.hint .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.important .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.note .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.seealso .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.tip .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .admonition.warning .admonition-title:before,.mdl-button--icon.mdl-button--mini-icon .material-icons,.mdl-button--icon.mdl-button--mini-icon a.download:before{top:0;left:0}.mdl-button--icon .mdl-button__ripple-container{border-radius:50%;-webkit-mask-image:-webkit-radial-gradient(circle,#fff,#000)}.mdl-button__ripple-container{display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:0;overflow:hidden}.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple,.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple{background-color:transparent}.mdl-button--primary.mdl-button--primary{color:#2196f3}.mdl-button--primary.mdl-button--primary .mdl-ripple{background:#fff}.mdl-button--primary.mdl-button--primary.mdl-button--fab,.mdl-button--primary.mdl-button--primary.mdl-button--raised{color:#fff;background-color:#2196f3}.mdl-button--accent.mdl-button--accent{color:#ff6e40}.mdl-button--accent.mdl-button--accent .mdl-ripple{background:#fff}.mdl-button--accent.mdl-button--accent.mdl-button--fab,.mdl-button--accent.mdl-button--accent.mdl-button--raised{color:#fff;background-color:#ff6e40}.mdl-button.mdl-button--disabled.mdl-button--disabled,.mdl-button[disabled][disabled]{color:rgba(0,0,0,.26);cursor:default;background-color:transparent}.mdl-button--fab.mdl-button--disabled.mdl-button--disabled,.mdl-button--fab[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26)}.mdl-button--raised.mdl-button--disabled.mdl-button--disabled,.mdl-button--raised[disabled][disabled]{background-color:rgba(0,0,0,.12);color:rgba(0,0,0,.26);box-shadow:none}.mdl-button--colored.mdl-button--disabled.mdl-button--disabled,.mdl-button--colored[disabled][disabled]{color:rgba(0,0,0,.26)}.admonition.attention .mdl-button .admonition-title:before,.admonition.caution .mdl-button .admonition-title:before,.admonition.danger .mdl-button .admonition-title:before,.admonition.error .mdl-button .admonition-title:before,.admonition.hint .mdl-button .admonition-title:before,.admonition.important .mdl-button .admonition-title:before,.admonition.note .mdl-button .admonition-title:before,.admonition.seealso .mdl-button .admonition-title:before,.admonition.tip .mdl-button .admonition-title:before,.admonition.warning .mdl-button .admonition-title:before,.mdl-button .admonition.attention .admonition-title:before,.mdl-button .admonition.caution .admonition-title:before,.mdl-button .admonition.danger .admonition-title:before,.mdl-button .admonition.error .admonition-title:before,.mdl-button .admonition.hint .admonition-title:before,.mdl-button .admonition.important .admonition-title:before,.mdl-button .admonition.note .admonition-title:before,.mdl-button .admonition.seealso .admonition-title:before,.mdl-button .admonition.tip .admonition-title:before,.mdl-button .admonition.warning .admonition-title:before,.mdl-button .material-icons,.mdl-button a.download:before{vertical-align:middle}.font-light{font-weight:300}.font-regular{font-weight:400}.font-heavy{font-weight:700}.left{text-align:left}.right{text-align:right}.center{text-align:center;margin-left:auto;margin-right:auto}.justify{text-align:justify}.hidden-sm{display:none}.container{width:100%;margin-left:auto;margin-right:auto}.row{position:relative;width:100%}.row [class^=col]{float:left;margin:.5rem 1%;min-height:.125rem}.row:after{content:"";display:table;clear:both}.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12{width:98%}.col-1-sm{width:6.33333%}.col-2-sm{width:14.66667%}.col-3-sm{width:23%}.col-4-sm{width:31.33333%}.col-5-sm{width:39.66667%}.col-6-sm{width:48%}.col-7-sm{width:56.33333%}.col-8-sm{width:64.66667%}.col-9-sm{width:73%}.col-10-sm{width:81.33333%}.col-11-sm{width:89.66667%}.col-12-sm{width:98%}@media only screen and (min-width:45em){.col-1{width:6.33333%}.col-2{width:14.66667%}.col-3{width:23%}.col-4{width:31.33333%}.col-5{width:39.66667%}.col-6{width:48%}.col-7{width:56.33333%}.col-8{width:64.66667%}.col-9{width:73%}.col-10{width:81.33333%}.col-11{width:89.66667%}.col-12{width:98%}.hidden-sm{display:block}}.row{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;flex-wrap:wrap}.row>[class*=col-]{display:flex;flex-direction:column}.admonition.attention .admonition-title:before,.admonition.caution .admonition-title:before,.admonition.danger .admonition-title:before,.admonition.error .admonition-title:before,.admonition.hint .admonition-title:before,.admonition.important .admonition-title:before,.admonition.note .admonition-title:before,.admonition.seealso .admonition-title:before,.admonition.tip .admonition-title:before,.admonition.warning .admonition-title:before,.material-icons,a.download:before{font-family:Material Icons;font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:"liga"}html{font-size:16px}body{display:block!important;background-color:#fafafa;font-size:1rem;line-height:1.5rem;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}.mdl-layout__content:focus{outline:none}.mdl-layout__content header.mdl-layout__drawer{display:none}.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:300px}@media screen and (max-width:1024px){.mdl-layout--fixed-drawer>.mdl-layout__content{margin-left:0}}a.download>code.download,blockquote,h1,h2,h3,h4,h5,h6,span.mdl-layout-title{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}.contents,.contents a,.globaltoc a.current,.toc-backref,.toctree-wrapper,.toctree-wrapper a,h1,h2,h3,h4,h5,h6{color:#048ccc!important}a{text-decoration:none}.page-content,.page-content dd,.page-content dl,.page-content dt,.page-content ol,.page-content p,.page-content table,.page-content td,.page-content th,.page-content ul{font-size:1rem}.brand{color:inherit;text-decoration:none}.section{overflow-x:auto}img{max-width:100%;display:block;margin-left:auto;margin-right:auto}div.figure p.caption{text-align:center;margin-top:.75rem}div.figure p.caption span.caption-number{font-style:normal}div.figure p.caption .caption-number:after{content:"\00a0"}.svg-icon{width:16px;height:16px;display:inline-block;fill:#f5f5f5;padding-right:5px;padding-top:4px;vertical-align:text-top}.admonition.attention a.download>i.admonition-title:before,.admonition.caution a.download>i.admonition-title:before,.admonition.danger a.download>i.admonition-title:before,.admonition.error a.download>i.admonition-title:before,.admonition.hint a.download>i.admonition-title:before,.admonition.important a.download>i.admonition-title:before,.admonition.note a.download>i.admonition-title:before,.admonition.seealso a.download>i.admonition-title:before,.admonition.tip a.download>i.admonition-title:before,.admonition.warning a.download>i.admonition-title:before,a.download>i.material-icons{position:relative;top:5px}a.download{text-decoration:none}.wrapper:after{content:"";display:table;clear:both}.wrapper{max-width:1090px;margin-right:auto;margin-left:auto;padding-right:45px;padding-left:30px}@media screen and (max-width:1024px){.wrapper{max-width:1120px;padding-right:15px;padding-left:15px}}.mdl-layout{margin-top:76px}.document{width:100%;margin:0 auto;display:flex}@media (min-width:1795px){.document{width:100%}}.document .page-content{width:100%;margin:0 auto;padding:0 12px}@media (min-width:992px){.document .page-content{width:90%;padding:0 5%}}@media (min-width:1200px){.document .page-content{width:calc(90% - 230px);padding:0 5%}}.document .side-doc-outline{width:230px}@media (max-width:1199px){.document .side-doc-outline{display:none}}.document .side-doc-outline--content{position:fixed;overflow-x:auto;overflow-y:auto;width:inherit;right:0}.document .side-doc-outline--content::-webkit-scrollbar{width:6px}.document .side-doc-outline--content::-webkit-scrollbar-track{border-radius:6px}.document .side-doc-outline--content::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:6px;box-shadow:0 0 0 1px hsla(0,0%,100%,.3)}@keyframes float-in{0%{transform:translateY(.5rem);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes float-out{0%{transform:translateY(0);opacity:1}to{transform:translateY(.5rem);opacity:0}}.page-content .headerlink{display:inline-block;text-decoration:none;margin-left:.8rem;color:inherit;opacity:0}.page-content .headerlink:hover{animation:float-in .2s cubic-bezier(.4,0,.2,1) 0s forwards}.page-content h1 .toc-backref,.page-content h2 .toc-backref,.page-content h3 .toc-backref,.page-content h4 .toc-backref,.page-content h5 .toc-backref,.page-content h6 .toc-backref{text-decoration:none}.page-content h1:hover .headerlink,.page-content h2:hover .headerlink,.page-content h3:hover .headerlink,.page-content h4:hover .headerlink,.page-content h5:hover .headerlink,.page-content h6:hover .headerlink{animation:float-in .2s cubic-bezier(.4,0,.2,1) 0s forwards}.page-content h1{font-size:2rem;line-height:2.25rem}.page-content h2{font-size:1.75rem;line-height:2rem;padding-top:1.5rem;margin-top:0;margin-bottom:1rem}.page-content h3{font-size:1.5rem;line-height:1.75rem;padding-top:1rem;margin-top:0;margin-bottom:.75rem}.page-content h4{font-size:1.25rem;line-height:1.5rem;padding-top:.75rem;margin-top:0;margin-bottom:.5rem}.page-content div.page-content h5{font-size:1.1rem;line-height:1.5rem;padding-top:2rem;margin-top:0;margin-bottom:1rem}.page-content div.page-content h6{font-size:1rem;line-height:1.5rem;padding-top:2rem;margin-top:0;margin-bottom:1rem}.admonition{padding:12px 20px;margin-top:10px;margin-bottom:10px}.admonition p.last{margin:16px}.admonition .admonition-title{font-size:16px;font-weight:700;color:#555;text-transform:uppercase;margin-top:7px}.admonition.note{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.note .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.note .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"info_outline";font-size:18px}.admonition.seealso{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.seealso .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.seealso .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"search";font-size:18px}.admonition.hint{border-left:4px solid #00bcd4;background-color:rgba(0,188,212,.1)}.admonition.hint .admonition-title{font-size:16px;font-weight:700;color:#00bcd4;margin-top:4px;margin-bottom:8px}.admonition.hint .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"help_outline";font-size:18px}.admonition.warning{border-left:4px solid #ffc107;background-color:rgba(255,193,7,.1)}.admonition.warning .admonition-title{font-size:16px;font-weight:700;color:#ffc107;margin-top:4px;margin-bottom:8px}.admonition.warning .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"warning";font-size:18px}.admonition.attention{border-left:4px solid #ffc107;background-color:rgba(255,193,7,.1)}.admonition.attention .admonition-title{font-size:16px;font-weight:700;color:#ffc107;margin-top:4px;margin-bottom:8px}.admonition.attention .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"warning";font-size:18px}.admonition.tip{border-left:4px solid #8bc34a;background-color:rgba(139,195,74,.1)}.admonition.tip .admonition-title{font-size:16px;font-weight:700;color:#8bc34a;margin-top:4px;margin-bottom:8px}.admonition.tip .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"lightbulb_outline";font-size:18px}.admonition.important{border-left:4px solid #8bc34a;background-color:rgba(139,195,74,.1)}.admonition.important .admonition-title{font-size:16px;font-weight:700;color:#8bc34a;margin-top:4px;margin-bottom:8px}.admonition.important .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"check_circle";font-size:18px}.admonition.error{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.error .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.error .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.admonition.caution{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.caution .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.caution .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.admonition.danger{border-left:4px solid #f44336;background-color:rgba(244,67,54,.1)}.admonition.danger .admonition-title{font-size:16px;font-weight:700;color:#f44336;margin-top:4px;margin-bottom:8px}.admonition.danger .admonition-title:before{position:relative;margin-right:5px;top:3px;content:"error_outline";font-size:18px}.page-content .highlight{margin:1px 0}.page-content .highlight pre{background:rgba(0,0,0,.05);color:rgba(0,0,0,.87);font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace;padding:.75rem;overflow:auto;overflow-y:hidden}.page-content .highlight pre .nd,.page-content .highlight pre .o{color:rgba(0,0,0,.87)}.page-content div.highlight-console div.highlight{background:none}.page-content .output .highlight pre{color:rgba(0,0,0,.87);background:#fafafa;border:1px solid #999;padding:.75rem}.page-content .code,.page-content code:not(.download){margin:0;border-radius:2px}.page-content .code,.page-content .code span.pre,.page-content code:not(.download),.page-content code:not(.download) span.pre{font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace}.page-content .viewcode-link{padding-left:2em;font-size:80%}.page-content .class>dt,.page-content .function>dt,.page-content .method>dt,.page-content .rubric{display:table;margin:10px 0;font-size:100%;line-height:normal;background:#e7f2fa;color:#2b98f0;border-top:3px solid #55adf3;padding:10px;position:relative}.page-content .class>dt .descclassname,.page-content .class>dt .descname,.page-content .function>dt .descclassname,.page-content .function>dt .descname,.page-content .method>dt .descclassname,.page-content .method>dt .descname,.page-content .rubric .descclassname,.page-content .rubric .descname{color:rgba(0,0,0,.87);background:#e7f2fa;padding:3px}.page-content .class>dt em,.page-content .function>dt em,.page-content .method>dt em,.page-content .rubric em{padding:0 2px}.page-content .rubric{margin:30px 0 10px}.page-content .field-body{padding-left:40px}.page-content .field-body ul{padding:0 0 0 16px;margin:0}.page-content .seealso .docutils>dt{float:left;clear:left;padding:0 6px}.page-content .seealso .docutils>dd{padding-left:6em}.page-content .nblast{padding-bottom:1em}.page-content pre{font-size:90%;background:#eee;color:#455a64;padding:16px 32px;width:auto;border-radius:4px;word-wrap:break-word}.page-content pre:hover:before{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;padding:0 .5rem;content:attr(click-to-copy);color:rgba(0,0,0,.5);border-radius:4px;position:relative;float:right;top:-.5rem;right:-.5rem;background:#c8c8c8;font-size:.8rem;cursor:pointer}.page-content blockquote{font-size:1rem;padding:0 1rem;border-left:3px solid rgba(0,0,0,.05)}.page-content blockquote:after{content:""!important;margin-left:0}.page-content blockquote:before{content:""!important}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list){margin:1.5rem 0;table-layout:fixed;max-width:100%;min-width:70%}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) td,.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) th{white-space:normal;overflow-wrap:break-word}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption{font-size:16px;margin:1rem 0 .8rem;white-space:normal}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption .caption-number{font-style:normal}.page-content table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) caption .caption-number:after{content:"\00a0"}.globaltoc .caption,.globaltoc .toc{display:none}.globaltoc ul{list-style-type:none;padding:0;margin:0}.globaltoc ul li{min-height:18px}.globaltoc ul li .link-wrapper{display:flex;justify-content:space-between}.globaltoc ul li .link-wrapper>a{padding:4px 0;display:block;width:100%;font-size:1rem;text-decoration:none;color:#757575}.globaltoc ul li .link-wrapper>a.current{font-weight:700}.globaltoc .nav-toggle{padding:0;float:right;display:flex;align-items:center;justify-content:center;height:36px}.globaltoc .nav-toggle>a{padding:0;margin-left:0;margin-right:4px;cursor:pointer}.globaltoc .nav-toggle>a>i{font-size:18px}.globaltoc .nav-toggle.show{transform:rotate(180deg)}.globaltoc .nav-toggle.show>a{margin-right:0;margin-left:4px}.globaltoc nav>ul>li>span.link-wrapper{padding-left:8px}.globaltoc nav>ul>li>ul>li>span.link-wrapper{padding-left:16px}.globaltoc nav>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:24px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:32px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:40px}.globaltoc nav>ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>span.link-wrapper{padding-left:48px}.localtoc{font-size:.75rem;padding-top:1rem}.localtoc .caption{padding-left:12px}.localtoc .caption-text{font-size:.9rem;font-weight:700}.localtoc>ul>li>a{display:none}.localtoc ul{padding:0;list-style-type:none}.localtoc li{padding-left:6px}.localtoc a{display:block;text-decoration:none;color:inherit;margin-top:8px;padding-left:8px;line-height:1.1rem}.localtoc a.current{padding-left:5px;border-left:3px solid;font-weight:700}.contents.topic,.toctree-wrapper{border-left:5px solid}.contents.topic>p.topic-title,.toctree-wrapper>p.caption{color:#757575;font-size:1rem;padding-left:14px}.contents.topic ul,.toctree-wrapper ul{padding-left:14px;list-style:none;line-height:30px}.contents.topic a,.toctree-wrapper a{font-size:1.2rem;text-decoration:none}.contents.topic a .pre,.toctree-wrapper a .pre{font-size:1rem}.contents.topic>ul>li>a,.toctree-wrapper>ul>li>a{font-size:1.3rem}.contents.topic>ul>li>a .pre,.toctree-wrapper>ul>li>a .pre{font-size:1.1rem}.page-content ul li{margin:.3rem 0}.page-content ul li p{margin:0}.page-content .option-list .option{font-family:Menlo,DejaVu Sans Mono,Liberation Mono,Consolas,Ubuntu Mono,Courier New,andale mono,lucida console,monospace}.page-content .option-list td{padding:.5rem;border:none}.mdl-layout__drawer{background-color:#fff}.mdl-layout__drawer::-webkit-scrollbar{width:6px}.mdl-layout__drawer::-webkit-scrollbar-track{border-radius:6px}.mdl-layout__drawer::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:6px;box-shadow:0 0 0 1px hsla(0,0%,100%,.3)}.mdl-layout__drawer>.mdl-layout-title{font-weight:700;text-align:right;margin:0;padding:0;line-height:32px;border-bottom:1px solid rgba(0,0,0,.1);min-height:64px}.mdl-layout__drawer>.mdl-layout-title .title{color:inherit;display:block;height:100%;width:100%;text-decoration:none}.mdl-layout__drawer>.mdl-layout-title .title>img.logo{width:100%;margin:0;padding:0}.mdl-layout__drawer>.mdl-layout-title .title-text{font-weight:700;text-align:right;padding:0 10px;margin:16px 0 8px;line-height:32px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;color:inherit;display:block}nav.breadcrumb>a.mdl-navigation__link{padding:0 8px;font-size:18px}@media (max-width:1199px){nav.breadcrumb{width:calc(100% - 64px)}nav.breadcrumb a.mdl-navigation__link.is-active{overflow-x:hidden;width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.admonition.attention nav.breadcrumb i.admonition-title:before,.admonition.caution nav.breadcrumb i.admonition-title:before,.admonition.danger nav.breadcrumb i.admonition-title:before,.admonition.error nav.breadcrumb i.admonition-title:before,.admonition.hint nav.breadcrumb i.admonition-title:before,.admonition.important nav.breadcrumb i.admonition-title:before,.admonition.note nav.breadcrumb i.admonition-title:before,.admonition.seealso nav.breadcrumb i.admonition-title:before,.admonition.tip nav.breadcrumb i.admonition-title:before,.admonition.warning nav.breadcrumb i.admonition-title:before,nav.breadcrumb .admonition.attention i.admonition-title:before,nav.breadcrumb .admonition.caution i.admonition-title:before,nav.breadcrumb .admonition.danger i.admonition-title:before,nav.breadcrumb .admonition.error i.admonition-title:before,nav.breadcrumb .admonition.hint i.admonition-title:before,nav.breadcrumb .admonition.important i.admonition-title:before,nav.breadcrumb .admonition.note i.admonition-title:before,nav.breadcrumb .admonition.seealso i.admonition-title:before,nav.breadcrumb .admonition.tip i.admonition-title:before,nav.breadcrumb .admonition.warning i.admonition-title:before,nav.breadcrumb a.mdl-navigation__link:not(.is-active),nav.breadcrumb i.material-icons{display:none}}div.mdl-layout__header{margin-top:77px}.mdl-layout__drawer-button{top:13px!important}div.mdl-layout__header-row.header-links{background:hsla(0,0%,100%,.2);width:100%;overflow-x:auto;overflow-y:hidden}div.mdl-layout__header-row.header-links a.mdl-navigation__link{font-size:1rem}div.mdl-layout__header-row.header-links a.mdl-navigation__link i{font-size:1.2rem;margin:0 8px;position:relative;bottom:-.1rem}div.mdl-layout__header-row.header-links a.mdl-navigation__link:hover{background-color:#2196f3;color:#eee}div.mdl-layout__header-row.header-links a.mdl-navigation__link[href="#"]{background-color:#2196f3;opacity:1;color:#fff}.site-title{font-weight:300!important;line-height:57px;letter-spacing:-1px;margin-bottom:0;float:left;color:#fff}.site-title,.site-title:visited{color:#424242}.site-header{position:fixed;top:0;width:100%;min-height:55px;padding-top:10px;padding-bottom:10px;background-color:#048ccc;z-index:10;font-weight:300;font-size:17px;border-bottom:1px solid #fff}.site-header-logo{width:120px;display:initial}.site-nav{float:right;line-height:57px}.site-nav .menu-icon,.site-nav .nav-trigger{display:none}.site-nav .page-link{color:#fff;line-height:1.5;font-weight:300}.site-nav .page-link:not(:last-child){margin-right:40px}.site-nav .page-link:hover{color:#fff;text-shadow:-.06ex 0 #fff,.06ex 0 #fff}.site-nav .page-link.page-current{color:#fff;text-decoration:underline}@media screen and (max-width:1024px){.site-nav{position:absolute;top:9px;right:15px;background-color:#178dc9;border-radius:2px;text-align:right}.site-nav label[for=nav-trigger]{display:block;float:right;width:36px;height:36px;z-index:2;cursor:pointer}.site-nav .menu-icon{display:block;float:right;width:36px;height:26px;line-height:0;padding-top:20px;text-align:center}.site-nav .menu-icon>svg{fill:#fff}.site-nav input~.trigger{clear:both;display:none}.site-nav input:checked~.trigger{display:block;padding-bottom:5px}.site-nav .page-link{padding:5px 10px;display:block;margin-left:20px}.site-nav .page-link:not(:last-child){margin-right:0}}footer.mdl-mini-footer{background-color:#212121}footer.mdl-mini-footer>div.mdl-mini-footer__left-section{margin-bottom:20px;display:flex;flex-direction:column}footer.mdl-mini-footer>div.mdl-mini-footer__left-section .mdl-logo{font-size:1.1rem}footer.mdl-mini-footer>div.mdl-mini-footer__right-section{font-size:.9rem;display:flex;flex-direction:column;justify-content:flex-end}footer.mdl-mini-footer>div.mdl-mini-footer__right-section a{color:inherit;font-weight:700;text-decoration:none}footer.mdl-mini-footer p.caption{display:none}.pagenation{width:100%;margin-top:80px;height:92px;background-color:#424242;display:flex}.pagenation #button-next,.pagenation #button-prev,.pagenation .button-common{text-transform:none;padding:0;height:92px;display:flex;justify-content:center;align-items:center;color:#fff}.pagenation #button-prev{margin-right:auto}.pagenation #button-prev .pagenation-text{text-align:left}.pagenation #button-next{margin-left:auto;flex-direction:row-reverse}.pagenation #button-next .pagenation-text{text-align:right}.pagenation-arrow-L{margin-right:20px}.pagenation-arrow-R{margin-left:20px}.pagenation-text{line-height:30px;font-size:20px}.pagenation-direction{opacity:.7;font-size:18px}@media screen and (max-width:1024px){.pagenation #button-prev{width:20%}.pagenation #button-next{width:80%}.pagenation #button-prev .pagenation-text{display:none}}@media screen and (min-width:1025px){.pagenation #button-next,.pagenation #button-prev{width:50%}.pagenation #button-prev .pagenation-text{display:block}}.site-footer{border-top:1px solid #f5f5f5;padding:30px 0;background-color:#424242;position:relative;z-index:10}.site-footer .footer-category-title{color:#048ccc}.site-footer a,.site-footer a:visited{color:#f5f5f5!important}.site-footer2{background-color:#424242;padding-top:40px;padding-bottom:10px;position:relative;z-index:10}.footer-heading{margin-bottom:15px}.contact-list,.social-media-list{list-style:none;margin-left:0}.footer-bottom-warning{font-size:80%;color:#fff;float:left}.footer-logo{width:200px;margin-bottom:30px;margin-top:30px}.footer-col{float:left;margin-bottom:15px;padding-left:15px}.footer-text{color:#f5f5f5}#waterfall-exp::-webkit-input-placeholder{color:#ccc}#waterfall-exp:-ms-input-placeholder{color:#ccc}#waterfall-exp::-moz-placeholder{color:#ccc}ul.search span.highlighted{font-weight:700}ul.search>li{margin-bottom:24px}#search-results ul{list-style:none;padding:0}#search-results ul li>a{text-decoration:none;font-size:1.2rem}a.download:before{content:"file_download";position:relative;top:5px;margin-right:5px}button.download{position:sticky;margin-left:1em}.mdl-card{margin:1em 1.5em 1em 0;display:inline-block;width:250px;min-height:140px;padding:18px}.mdl-card:hover{box-shadow:0 10px 20px rgba(0,0,0,.25),0 6px 6px rgba(0,0,0,.22);color:#000;cursor:pointer}.mdl-card__title{padding:0 0 1em;font-size:18px;color:#444}.mdl-card__supporting-text{line-height:1.5rem;padding:0;width:100%}.head-card.mdl-card{width:auto;display:block;max-width:800px;padding:24px}.head-card>.mdl-card__title{padding-bottom:0;height:60px;font-weight:700;text-transform:uppercase}.head-card>.mdl-card__menu{color:#fff}.head-card>.mdl-card__actions{padding:0}.cards{display:flex;flex-direction:row;flex-wrap:wrap} /*# sourceMappingURL=/sphinx_materialdesign_theme.css.map */ \ No newline at end of file diff --git a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css.map b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css.map index 61d11807ca0b..428795213db6 100644 --- a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css.map +++ b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.css.map @@ -1 +1 @@ -{"version":3,"sources":["../../node_modules/material-design-lite/src/shadow/_shadow.scss","../../node_modules/material-design-lite/src/_mixins.scss","../../node_modules/material-design-lite/src/data-table/_data-table.scss","../../node_modules/material-design-lite/src/_variables.scss","../../node_modules/material-design-lite/src/footer/_mini_footer.scss","../../node_modules/material-design-lite/src/card/_card.scss","../../node_modules/material-design-lite/src/button/_button.scss","../scss/grid/_simplegrid.scss","../scss/fonts/_material-icons.scss","../scss/_root.scss","../scss/_variables.scss","../scss/layout/_layout.scss","../scss/headerings/_headerings.scss","../scss/admonitions/_admonitions.scss","../scss/code/_code.scss","../scss/blockquote/_blockquote.scss","../scss/tables/_tables.scss","../scss/toc/_globaltoc.scss","../scss/toc/_localtoc.scss","../scss/toc/_toctree.scss","../scss/lists/_lists.scss","../scss/drawer/_drawer.scss","../scss/header/_header.scss","../scss/footer/_footer.scss","../scss/search/_search.scss","../scss/downloadlink/_downloadlink.scss","../scss/card/_card.scss"],"names":[],"mappings":"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","file":"sphinx_materialdesign_theme.css","sourceRoot":"../../src/js","sourcesContent":["/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https:///www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n.mdl-shadow--2dp {\n @include shadow-2dp();\n}\n\n.mdl-shadow--3dp {\n @include shadow-3dp();\n}\n\n.mdl-shadow--4dp {\n @include shadow-4dp();\n}\n\n.mdl-shadow--6dp {\n @include shadow-6dp();\n}\n\n.mdl-shadow--8dp {\n @include shadow-8dp();\n}\n\n.mdl-shadow--16dp {\n @include shadow-16dp();\n}\n\n.mdl-shadow--24dp {\n @include shadow-24dp();\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Typography */\n\n@mixin typo-preferred-font($usePreferred: true) {\n @if $usePreferred {\n font-family: $preferred_font;\n }\n}\n\n@mixin typo-display-4($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 112px;\n font-weight: 300;\n line-height: 1;\n letter-spacing: -0.04em;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-3($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 56px;\n font-weight: 400;\n line-height: 1.35;\n letter-spacing: -0.02em;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-2($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 45px;\n font-weight: 400;\n line-height: 48px;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-1($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 34px;\n font-weight: 400;\n line-height: 40px;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-headline($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 24px;\n font-weight: 400;\n line-height: 32px;\n -moz-osx-font-smoothing: grayscale;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-title($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 20px;\n font-weight: 500;\n line-height: 1;\n letter-spacing: 0.02em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-subhead($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 16px;\n font-weight: 400;\n line-height: 24px;\n letter-spacing: 0.04em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-subhead-2($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 16px;\n font-weight: 400;\n line-height: 28px;\n letter-spacing: 0.04em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-body-2($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n @if $usePreferred {\n font-weight: 500;\n } @else {\n font-weight: bold;\n }\n line-height: 24px;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-body-1($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 400;\n line-height: 24px;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-caption($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 12px;\n font-weight: 400;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-blockquote($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n position: relative;\n font-size: 24px;\n font-weight: 300;\n font-style: italic;\n line-height: 1.35;\n letter-spacing: 0.08em;\n\n &:before {\n position: absolute;\n left: -0.5em;\n content: '“';\n }\n\n &:after {\n content: '”';\n margin-left: -0.05em;\n }\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-menu($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-button($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 500;\n text-transform: uppercase;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-icon() {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n word-wrap: normal;\n font-feature-settings: 'liga';\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* Shadows */\n\n// Focus shadow mixin.\n@mixin focus-shadow() {\n box-shadow: 0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);\n}\n\n@mixin shadow-2dp() {\n box-shadow: 0 2px 2px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 1px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),\n 0 1px 5px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);\n}\n@mixin shadow-3dp() {\n box-shadow: 0 3px 4px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 3px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),\n 0 1px 8px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);\n}\n@mixin shadow-4dp() {\n box-shadow: 0 4px 5px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 1px 10px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n@mixin shadow-6dp() {\n box-shadow: 0 6px 10px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 1px 18px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n@mixin shadow-8dp() {\n box-shadow: 0 8px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 14px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n@mixin shadow-16dp() {\n box-shadow: 0 16px 24px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 6px 30px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n@mixin shadow-24dp() {\n box-shadow: 0 9px 46px 8px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 11px 15px -7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 24px 38px 3px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n/* Animations */\n\n@mixin material-animation-fast-out-slow-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-fast-out-slow-in;\n}\n\n@mixin material-animation-linear-out-slow-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-linear-out-slow-in;\n}\n\n@mixin material-animation-fast-out-linear-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-fast-out-linear-in;\n}\n\n@mixin material-animation-default($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-default;\n}\n\n/* Dialog */\n\n@mixin dialog-width($units:5) {\n @if(type_of($units) != 'number') {\n @error \"The unit given to dialog-width should be a number.\";\n }\n // 56dp is the base unit width for Dialogs.\n // With 5 units being the number of units for a mobile device.\n // https://goo.gl/sK2O5o\n width: $units * 56px;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n.mdl-data-table {\n position: relative;\n border: $data-table-dividers;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: $data-table-font-size;\n background-color: unquote(\"rgb(#{$color-white})\");\n\n thead {\n padding-bottom: 3px;\n\n .mdl-data-table__select {\n margin-top: 0;\n }\n }\n\n tbody {\n tr {\n position: relative;\n height: $data-table-row-height;\n @include material-animation-default(0.28s);\n transition-property: background-color;\n\n &.is-selected {\n background-color: $data-table-selection-color;\n }\n\n &:hover {\n background-color: $data-table-hover-color;\n }\n }\n }\n\n td, th {\n padding: 0 $data-table-column-padding 12px $data-table-column-padding;\n text-align: right;\n\n &:first-of-type {\n padding-left: 24px;\n }\n\n &:last-of-type {\n padding-right: 24px;\n }\n }\n\n td {\n position: relative;\n vertical-align: middle;\n height: $data-table-row-height;\n border-top: $data-table-dividers;\n border-bottom: $data-table-dividers;\n padding-top: $data-table-cell-top;\n box-sizing: border-box;\n\n .mdl-data-table__select {\n vertical-align: middle;\n }\n }\n\n th {\n position: relative;\n vertical-align: bottom;\n text-overflow: ellipsis;\n @include typo-body-2();\n height: $data-table-row-height;\n font-size: $data-table-header-font-size;\n color: $data-table-header-color;\n padding-bottom: 8px;\n box-sizing: border-box;\n\n &.mdl-data-table__header--sorted-ascending,\n &.mdl-data-table__header--sorted-descending {\n color: $data-table-header-sorted-color;\n &:before {\n @include typo-icon;\n font-size: $data-table-header-sort-icon-size;\n content: \"\\e5d8\";\n margin-right: 5px;\n vertical-align: sub;\n }\n &:hover {\n cursor: pointer;\n &:before {\n color: $data-table-header-sorted-icon-hover-color;\n }\n }\n }\n &.mdl-data-table__header--sorted-descending:before {\n content: \"\\e5db\";\n }\n }\n}\n\n.mdl-data-table__select {\n width: 16px;\n}\n\n.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric {\n text-align: left;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*------------------------------------*\\\n $CONTENTS\n\\*------------------------------------*/\n/**\n * STYLE GUIDE VARIABLES------------------Declarations of Sass variables\n * -----Typography\n * -----Colors\n * -----Textfield\n * -----Switch\n * -----Spinner\n * -----Radio\n * -----Menu\n * -----List\n * -----Layout\n * -----Icon toggles\n * -----Footer\n * -----Column\n * -----Checkbox\n * -----Card\n * -----Button\n * -----Animation\n * -----Progress\n * -----Badge\n * -----Shadows\n * -----Grid\n * -----Data table\n * -----Dialog\n * -----Snackbar\n * -----Tooltip\n * -----Chip\n *\n * Even though all variables have the `!default` directive, most of them\n * should not be changed as they are dependent one another. This can cause\n * visual distortions (like alignment issues) that are hard to track down\n * and fix.\n */\n\n\n/* ========== TYPOGRAPHY ========== */\n\n/* We're splitting fonts into \"preferred\" and \"performance\" in order to optimize\n page loading. For important text, such as the body, we want it to load\n immediately and not wait for the web font load, whereas for other sections,\n such as headers and titles, we're OK with things taking a bit longer to load.\n We do have some optional classes and parameters in the mixins, in case you\n definitely want to make sure you're using the preferred font and don't mind\n the performance hit.\n We should be able to improve on this once CSS Font Loading L3 becomes more\n widely available.\n*/\n$preferred_font: 'Roboto', 'Helvetica', 'Arial', sans-serif !default;\n$performance_font: 'Helvetica', 'Arial', sans-serif !default;\n\n/* ========== COLORS ========== */\n\n/**\n*\n* Material design color palettes.\n* @see http://www.google.com/design/spec/style/color.html\n*\n**/\n\n@import \"color-definitions\";\n@import \"functions\";\n\n/* ========== IMAGES ========== */\n$image_path: '/images' !default;\n\n/* ========== Color & Themes ========== */\n\n// Define whether individual color palette items should have classes created.\n// Setting this to true will remove individual color classes for each color in the palettes.\n// To improve overall performance (assuming they aren't used) by:\n// * Saving server bandwidth sending the extra classes\n// * Save client computation against the classes\n// it is RECOMMENDED you set this to true.\n$trim-color-classes: false !default;\n\n// Use color primarily for emphasis. Choose colors that fit with\n// your brand and provide good contrast between visual components.\n$color-primary: $palette-indigo-500 !default;\n$color-primary-dark: $palette-indigo-700 !default;\n$color-accent: $palette-pink-A200 !default;\n\n// Our primary is dark, so use $color-dark-contrast for overlaid text.\n$color-primary-contrast: $color-dark-contrast !default;\n// Our accent is dark, so use $color-dark-contrast for overlaid text.\n$color-accent-contrast: $color-dark-contrast !default;\n\n// Replace all colors with placeholders if we're generating a template.\n@if $styleguide-generate-template == true {\n $color-primary: '$color-primary';\n $color-primary-dark: '$color-primary-dark';\n $color-accent: '$color-accent';\n $color-primary-contrast: '$color-primary-contrast';\n $color-accent-contrast: '$color-accent-contrast';\n}\n\n/* ========== Typography ========== */\n\n// We use the following default color styles: text-color-primary and\n// text-color-secondary. For light themes, use text-color-primary-inverse\n// and text-color-secondary-inverse.\n\n$text-color-primary: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$text-link-color: unquote(\"rgb(#{$color-accent})\") !default;\n\n// Define whether to target elements directly for typographic enhancements.\n// Turning this off means you need to use mdl-* classes more often.\n// Other components may also fail to adhere to MD without these rules.\n// It is strongly recommended you leave this as true.\n\n$target-elements-directly: true !default;\n\n/* ========== Components ========== */\n\n/* ========== Standard Buttons ========== */\n\n// Default button colors.\n$button-primary-color: unquote(\"rgba(#{$palette-grey-500}, 0.20)\") !default;\n$button-secondary-color: unquote(\"rgb(#{$color-black})\") !default;\n$button-hover-color: $button-primary-color !default;\n$button-active-color: unquote(\"rgba(#{$palette-grey-500}, 0.40)\") !default;\n$button-focus-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n// Colored button colors.\n$button-primary-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-secondary-color-alt: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n$button-hover-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-active-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-focus-color-alt: $button-focus-color !default;\n\n// Ripple color for colored raised buttons.\n$button-ripple-color-alt: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n\n// Disabled button colors.\n$button-primary-color-disabled: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n$button-secondary-color-disabled: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n// FAB colors and sizes.\n$button-fab-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-hover-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-active-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-text-color-alt: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n$button-fab-ripple-color-alt: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n\n// Icon button colors and sizes.\n$button-icon-color: unquote(\"rgb(#{$palette-grey-700})\") !default;\n$button-icon-focus-color: $button-focus-color !default;\n\n/* ========== Icon Toggles ========== */\n\n$icon-toggle-color: unquote(\"rgb(#{$palette-grey-700})\") !default;\n$icon-toggle-focus-color: $button-focus-color !default;\n$icon-toggle-checked-color: unquote(\"rgb(#{$color-primary})\") !default;\n$icon-toggle-checked-focus-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$icon-toggle-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n/* ========== Radio Buttons ========== */\n\n$radio-color: unquote(\"rgb(#{$color-primary})\") !default;\n$radio-off-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$radio-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n/* ========== Ripple effect ========== */\n\n$ripple-bg-color: unquote(\"rgb(#{$color-light-contrast})\") !default;\n\n/* ========== Layout ========== */\n\n$layout-nav-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n\n// Drawer\n$layout-drawer-bg-color: unquote(\"rgb(#{$palette-grey-50})\") !default;\n$layout-drawer-border-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$layout-text-color: unquote(\"rgb(#{$palette-grey-800})\") !default;\n$layout-drawer-navigation-color: #757575 !default;\n$layout-drawer-navigation-link-active-background: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$layout-drawer-navigation-link-active-color: unquote(\"rgb(#{$color-light-contrast})\") !default;\n\n// Header\n$layout-header-bg-color: unquote(\"rgb(#{$color-primary})\") !default;\n$layout-header-text-color: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n$layout-header-nav-hover-color: unquote(\"rgba(#{$palette-grey-700}, 0.6)\") !default;\n$layout-header-tab-text-color: unquote(\"rgba(#{$color-primary-contrast}, 0.6)\") !default;\n\n// Tabs\n$layout-header-tab-highlight: unquote(\"rgb(#{$color-accent})\") !default;\n\n/* ========== Content Tabs ========== */\n\n$tab-highlight-color: unquote(\"rgb(#{$color-primary})\") !default;\n$tab-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$tab-active-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$tab-border-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n\n/* ========== Checkboxes ========== */\n\n$checkbox-color: unquote(\"rgb(#{$color-primary})\") !default;\n$checkbox-off-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$checkbox-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$checkbox-focus-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$checkbox-image-path: $image_path;\n\n/* ========== Switches ========== */\n\n$switch-color: unquote(\"rgb(#{$color-primary})\") !default;\n$switch-faded-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$switch-thumb-color: $switch-color !default;\n$switch-track-color: unquote(\"rgba(#{$color-primary}, 0.5)\") !default;\n\n$switch-off-thumb-color: unquote(\"rgb(#{$palette-grey-50})\") !default;\n$switch-off-track-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$switch-disabled-thumb-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n$switch-disabled-track-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n/* ========== Spinner ========== */\n\n$spinner-color-1: unquote(\"rgb(#{$palette-blue-400})\") !default;\n$spinner-color-2: unquote(\"rgb(#{$palette-red-500})\") !default;\n$spinner-color-3: unquote(\"rgb(#{$palette-yellow-600})\") !default;\n$spinner-color-4: unquote(\"rgb(#{$palette-green-500})\") !default;\n\n$spinner-single-color: unquote(\"rgb(#{$color-primary})\") !default;\n\n/* ========== Text fields ========== */\n\n$input-text-background-color: transparent !default;\n$input-text-label-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$input-text-bottom-border-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n$input-text-highlight-color: unquote(\"rgb(#{$color-primary})\") !default;\n$input-text-disabled-color: $input-text-bottom-border-color !default;\n$input-text-disabled-text-color: $input-text-label-color !default;\n$input-text-error-color: unquote(\"rgb(#{$palette-red-A700})\") !default;\n\n/* ========== Card ========== */\n\n$card-background-color: unquote(\"rgb(#{$color-white})\") !default;\n$card-text-color: unquote(\"rgb(#{$color-black})\") !default;\n$card-image-placeholder-color: unquote(\"rgb(#{$color-accent})\") !default;\n$card-supporting-text-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$card-border-color: rgba(0,0,0,0.1) !default;\n$card-subtitle-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n\n/* ========== Sliders ========== */\n\n$range-bg-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$range-color: unquote(\"rgb(#{$color-primary})\") !default;\n$range-faded-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$range-bg-focus-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n/* ========== Progress ========== */\n$progress-main-color: unquote(\"rgb(#{$color-primary})\") !default;\n$progress-secondary-color: unquote(\"rgba(#{$color-primary-contrast}, 0.7)\") !default;\n$progress-fallback-buffer-color: unquote(\"rgba(#{$color-primary-contrast}, 0.9)\") !default;\n$progress-image-path: $image_path;\n\n/* ========== List ========== */\n\n$list-main-text-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$list-supporting-text-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$list-icon-color: unquote(\"rgb(#{$palette-grey-600})\") !default;\n$list-avatar-color: white !default;\n\n/* ========== Item ========== */\n\n// Default Item Colors\n$default-item-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$default-item-outline-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n$default-item-hover-bg-color: unquote(\"rgb(#{$palette-grey-200})\") !default;\n$default-item-focus-bg-color: unquote(\"rgb(#{$palette-grey-200})\") !default;\n$default-item-active-bg-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$default-item-divider-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n// Disabled Button Colors\n$disabled-item-text-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n\n/* ========== Dropdown menu ========== */\n\n$default-dropdown-bg-color: unquote(\"rgb(#{$color-white})\") !default;\n\n/* ========== Tooltips ========== */\n\n$tooltip-text-color: unquote(\"rgb(#{$color-white})\") !default;\n$tooltip-background-color: unquote(\"rgba(#{$palette-grey-700}, 0.9)\") !default;\n\n/* ========== Footer ========== */\n\n$footer-bg-color: unquote(\"rgb(#{$palette-grey-800})\") !default;\n$footer-color: unquote(\"rgb(#{$palette-grey-500})\") !default;\n$footer-heading-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$footer-button-fill-color: $footer-color !default;\n$footer-underline-color: $footer-color !default;\n\n\n/* TEXTFIELD */\n\n$input-text-font-size: 16px !default;\n$input-text-width: 100% !default;\n$input-text-padding: 4px !default;\n$input-text-vertical-spacing: 20px !default;\n\n$input-text-button-size: 32px !default;\n$input-text-floating-label-fontsize: 12px !default;\n$input-text-expandable-icon-top: 16px !default;\n\n\n/* SWITCH */\n\n$switch-label-font-size: 16px !default;\n$switch-label-height: 24px !default;\n$switch-track-height: 14px !default;\n$switch-track-length: 36px !default;\n$switch-thumb-size: 20px !default;\n$switch-track-top: ($switch-label-height - $switch-track-height) / 2 !default;\n$switch-thumb-top: ($switch-label-height - $switch-thumb-size) / 2 !default;\n$switch-ripple-size: $switch-label-height * 2 !default;\n$switch-helper-size: 8px !default;\n\n/* SPINNER */\n\n$spinner-size: 28px !default;\n$spinner-stroke-width: 3px !default;\n\n// Amount of circle the arc takes up.\n$spinner-arc-size: 270deg !default;\n// Time it takes to expand and contract arc.\n$spinner-arc-time: 1333ms !default;\n// How much the start location of the arc should rotate each time.\n$spinner-arc-start-rot: 216deg !default;\n\n$spinner-duration: 360 * $spinner-arc-time / (\n strip-units($spinner-arc-start-rot + (360deg - $spinner-arc-size)));\n\n\n/* RADIO */\n\n$radio-label-font-size: 16px !default;\n$radio-label-height: 24px !default;\n$radio-button-size: 16px !default;\n$radio-inner-margin: $radio-button-size / 4;\n$radio-padding: 8px !default;\n$radio-top-offset: ($radio-label-height - $radio-button-size) / 2;\n$radio-ripple-size: 42px !default;\n\n\n/* MENU */\n\n$menu-expand-duration: 0.3s !default;\n$menu-fade-duration: 0.2s !default;\n\n/* LIST */\n\n$list-border: 8px !default;\n$list-min-height: 48px !default;\n$list-min-padding: 16px !default;\n$list-bottom-padding: 20px !default;\n$list-avatar-text-left-distance: 72px !default;\n$list-icon-text-left-distance: 72px !default;\n\n$list-avatar-size: 40px !default;\n$list-icon-size: 24px !default;\n\n$list-two-line-height: 72px !default;\n$list-three-line-height: 88px !default;\n\n/* LAYOUT */\n\n$layout-drawer-narrow: 240px !default;\n$layout-drawer-wide: 456px !default;\n$layout-drawer-width: $layout-drawer-narrow !default;\n\n$layout-header-icon-size: 32px !default;\n$layout-screen-size-threshold: 1024px !default;\n$layout-header-icon-margin: 24px !default;\n$layout-drawer-button-mobile-size: 32px !default;\n$layout-drawer-button-desktop-size: 48px !default;\n\n$layout-header-mobile-row-height: 56px !default;\n$layout-mobile-header-height: $layout-header-mobile-row-height;\n$layout-header-desktop-row-height: 64px !default;\n$layout-desktop-header-height: $layout-header-desktop-row-height;\n\n$layout-header-desktop-baseline: 80px !default;\n$layout-header-mobile-baseline: 72px !default;\n$layout-header-mobile-indent: 16px !default;\n$layout-header-desktop-indent: 40px !default;\n\n$layout-tab-font-size: 14px !default;\n$layout-tab-bar-height: 48px !default;\n$layout-tab-mobile-padding: 12px !default;\n$layout-tab-desktop-padding: 24px !default;\n$layout-tab-highlight-thickness: 2px !default;\n\n\n/* ICON TOGGLE */\n\n$icon-toggle-size: 32px !default;\n$icon-toggle-font-size: 24px !default;\n$icon-toggle-ripple-size: 36px !default;\n\n/* FOOTER */\n\n/*mega-footer*/\n$footer-min-padding: 16px !default;\n$footer-padding-sides: 40px !default;\n$footer-heading-font-size: 14px !default;\n$footer-heading-line-height: (1.7 * $footer-heading-font-size) !default;\n$footer-btn-size: 36px !default;\n\n/*mini-footer*/\n$padding: 16px !default;\n$footer-heading-font-size: 24px !default;\n$footer-heading-line-height: (1.5 * $footer-heading-font-size) !default;\n$footer-btn-size: 36px !default;\n\n/* CHECKBOX */\n\n$checkbox-label-font-size: 16px !default;\n$checkbox-label-height: 24px !default;\n$checkbox-button-size: 16px !default;\n$checkbox-inner-margin: 2px !default;\n$checkbox-padding: 8px !default;\n$checkbox-top-offset:\n($checkbox-label-height - $checkbox-button-size - $checkbox-inner-margin) / 2;\n$checkbox-ripple-size: $checkbox-label-height * 1.5;\n\n/* CARD */\n\n/* Card dimensions */\n$card-width: 330px !default;\n$card-height: 200px !default;\n$card-font-size: 16px !default;\n$card-title-font-size: 24px !default;\n$card-subtitle-font-size: 14px !default;\n$card-horizontal-padding: 16px !default;\n$card-vertical-padding: 16px !default;\n\n$card-title-perspective-origin-x: 165px !default;\n$card-title-perspective-origin-y: 56px !default;\n\n$card-title-transform-origin-x: 165px !default;\n$card-title-transform-origin-y: 56px !default;\n\n$card-title-text-transform-origin-x: 149px !default;\n$card-title-text-transform-origin-y: 48px !default;\n\n$card-supporting-text-font-size: 1rem !default;\n$card-supporting-text-line-height: 18px !default;\n\n$card-actions-font-size: 16px !default;\n\n$card-title-text-font-weight: 300 !default;\n$card-z-index: 1 !default;\n\n/* Cover image */\n$card-cover-image-height: 186px !default;\n$card-background-image-url: '' !default;\n\n\n/* BUTTON */\n/**\n *\n * Dimensions\n *\n */\n$button-min-width: 64px !default;\n$button-height: 36px !default;\n$button-padding: 16px !default;\n$button-margin: 4px !default;\n$button-border-radius: 2px !default;\n\n$button-fab-size: 56px !default;\n$button-fab-size-mini: 40px !default;\n$button-fab-font-size: 24px !default;\n\n$button-icon-size: 32px !default;\n$button-icon-size-mini: 24px !default;\n\n\n/* ANIMATION */\n$animation-curve-fast-out-slow-in: cubic-bezier(0.4, 0, 0.2, 1) !default;\n$animation-curve-linear-out-slow-in: cubic-bezier(0, 0, 0.2, 1) !default;\n$animation-curve-fast-out-linear-in: cubic-bezier(0.4, 0, 1, 1) !default;\n\n$animation-curve-default: $animation-curve-fast-out-slow-in !default;\n\n\n/* PROGRESS */\n$bar-height: 4px !default;\n\n/* BADGE */\n$badge-font-size: 12px !default;\n$badge-color: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n$badge-color-inverse: unquote(\"rgb(#{$color-accent})\") !default;\n$badge-background: unquote(\"rgb(#{$color-accent})\") !default;\n$badge-background-inverse: unquote(\"rgba(#{$color-accent-contrast},0.2)\") !default;\n$badge-size : 22px !default;\n$badge-padding: 2px !default;\n$badge-overlap: 12px !default;\n\n/* SHADOWS */\n\n$shadow-key-umbra-opacity: 0.2 !default;\n$shadow-key-penumbra-opacity: 0.14 !default;\n$shadow-ambient-shadow-opacity: 0.12 !default;\n\n/* GRID */\n\n$grid-desktop-columns: 12 !default;\n$grid-desktop-gutter: 16px !default;\n$grid-desktop-margin: 16px !default;\n\n$grid-desktop-breakpoint: 840px !default;\n\n$grid-tablet-columns: 8 !default;\n$grid-tablet-gutter: $grid-desktop-gutter !default;\n$grid-tablet-margin: $grid-desktop-margin !default;\n\n$grid-tablet-breakpoint: 480px !default;\n\n$grid-phone-columns: 4 !default;\n$grid-phone-gutter: $grid-desktop-gutter !default;\n$grid-phone-margin: $grid-desktop-margin !default;\n\n$grid-cell-default-columns: $grid-phone-columns !default;\n$grid-max-columns: $grid-desktop-columns !default;\n\n/* DATA TABLE */\n\n$data-table-font-size: 13px !default;\n$data-table-header-font-size: 12px !default;\n$data-table-header-sort-icon-size: 16px !default;\n\n$data-table-header-color: rgba(#000, 0.54) !default;\n$data-table-header-sorted-color: rgba(#000, 0.87) !default;\n$data-table-header-sorted-icon-hover-color: rgba(#000, 0.26) !default;\n$data-table-divider-color: rgba(#000, 0.12) !default;\n\n$data-table-hover-color: #eeeeee !default;\n$data-table-selection-color: #e0e0e0 !default;\n\n$data-table-dividers: 1px solid $data-table-divider-color !default;\n\n$data-table-row-height: 48px !default;\n$data-table-last-row-height: 56px !default;\n$data-table-header-height: 56px !default;\n\n$data-table-column-spacing: 36px !default;\n$data-table-column-padding: $data-table-column-spacing / 2;\n\n$data-table-card-header-height: 64px !default;\n$data-table-card-title-top: 20px !default;\n$data-table-card-padding: 24px !default;\n$data-table-button-padding-right: 16px !default;\n$data-table-cell-top: $data-table-card-padding / 2;\n\n/* DIALOG */\n$dialog-content-color: $card-supporting-text-text-color;\n\n/* SNACKBAR */\n\n// Hard coded since the color is not present in any palette.\n$snackbar-background-color: #323232 !default;\n$snackbar-tablet-breakpoint: $grid-tablet-breakpoint;\n$snackbar-action-color: unquote(\"rgb(#{$color-accent})\") !default;\n\n/* TOOLTIP */\n$tooltip-font-size: 10px !default;\n$tooltip-font-size-large: 14px !default;\n\n/* CHIP */\n$chip-bg-color: rgb(222, 222, 222) !default;\n$chip-bg-active-color: rgb(214, 214, 214) !default;\n$chip-height: 32px !default;\n$chip-font-size: 13px !default; \n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https:///www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n\n.mdl-mini-footer {\n display: flex;\n flex-flow: row wrap;\n justify-content: space-between;\n\n padding: ($padding * 2) $padding;\n\n color: $footer-color;\n background-color: $footer-bg-color;\n\n &:after {\n content: '';\n display: block;\n }\n\n & .mdl-logo {\n line-height: $footer-btn-size;\n }\n}\n\n.mdl-mini-footer--link-list,\n.mdl-mini-footer__link-list {\n display: flex;\n flex-flow: row nowrap;\n\n list-style: none;\n\n margin: 0;\n padding: 0;\n\n & li {\n margin-bottom: 0;\n margin-right: $padding;\n\n @media screen and (min-width: 760px) {\n line-height: $footer-btn-size;\n }\n }\n\n & a {\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n }\n}\n\n.mdl-mini-footer--left-section,\n.mdl-mini-footer__left-section {\n display: inline-block;\n order: 0;\n}\n\n.mdl-mini-footer--right-section,\n.mdl-mini-footer__right-section {\n display: inline-block;\n order: 1;\n}\n\n.mdl-mini-footer--social-btn,\n.mdl-mini-footer__social-btn {\n width: $footer-btn-size;\n height: $footer-btn-size;\n\n padding: 0;\n margin: 0;\n\n background-color: $footer-button-fill-color;\n\n border: none;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n\n.mdl-card {\n display: flex;\n flex-direction: column;\n font-size: $card-font-size;\n font-weight: 400;\n min-height: $card-height;\n overflow: hidden;\n width: $card-width;\n z-index: $card-z-index;\n position: relative;\n background: $card-background-color;\n border-radius: 2px;\n box-sizing: border-box;\n}\n\n.mdl-card__media {\n background-color: $card-image-placeholder-color;\n background-repeat: repeat;\n background-position: 50% 50%;\n background-size: cover;\n background-origin: padding-box;\n background-attachment: scroll;\n box-sizing: border-box;\n}\n\n.mdl-card__title {\n align-items: center;\n color: $card-text-color;\n display: block;\n display: flex;\n justify-content: stretch;\n line-height: normal;\n padding: $card-vertical-padding $card-horizontal-padding;\n perspective-origin: $card-title-perspective-origin-x $card-title-perspective-origin-y;\n transform-origin: $card-title-transform-origin-x $card-title-transform-origin-y;\n box-sizing: border-box;\n\n &.mdl-card--border {\n border-bottom: 1px solid $card-border-color;\n }\n}\n\n.mdl-card__title-text {\n align-self: flex-end;\n color: inherit;\n display: block;\n display: flex;\n font-size: $card-title-font-size;\n font-weight: $card-title-text-font-weight;\n line-height: normal;\n overflow: hidden;\n transform-origin: $card-title-text-transform-origin-x $card-title-text-transform-origin-y;\n margin: 0;\n}\n\n.mdl-card__subtitle-text {\n font-size: $card-subtitle-font-size;\n color: $card-subtitle-color;\n margin: 0;\n}\n\n.mdl-card__supporting-text {\n color: $card-supporting-text-text-color;\n font-size: $card-supporting-text-font-size;\n line-height: $card-supporting-text-line-height;\n overflow: hidden;\n padding: $card-vertical-padding $card-horizontal-padding;\n width: 90%;\n\n &.mdl-card--border {\n border-bottom: 1px solid $card-border-color;\n }\n}\n\n.mdl-card__actions {\n font-size: $card-actions-font-size;\n line-height: normal;\n width: 100%;\n background-color: rgba(0,0,0,0);\n padding: 8px;\n box-sizing: border-box;\n\n &.mdl-card--border {\n border-top: 1px solid $card-border-color;\n }\n}\n\n.mdl-card--expand {\n flex-grow: 1;\n}\n\n\n.mdl-card__menu {\n position: absolute;\n right: 16px;\n top: 16px;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https:///www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n// The button component. Defaults to a flat button.\n.mdl-button {\n background: transparent;\n border: none;\n border-radius: $button-border-radius;\n color: $button-secondary-color;\n position: relative;\n height: $button-height;\n margin: 0;\n min-width: $button-min-width;\n padding: 0 $button-padding;\n display: inline-block;\n @include typo-button();\n overflow: hidden;\n will-change: box-shadow;\n transition: box-shadow 0.2s $animation-curve-fast-out-linear-in,\n background-color 0.2s $animation-curve-default,\n color 0.2s $animation-curve-default;\n outline: none;\n cursor: pointer;\n text-decoration: none;\n text-align: center;\n line-height: $button-height;\n vertical-align: middle;\n\n &::-moz-focus-inner {\n border: 0;\n }\n\n &:hover {\n background-color: $button-hover-color;\n }\n\n &:focus:not(:active) {\n background-color: $button-focus-color;\n }\n\n &:active {\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n color: $button-primary-color-alt;\n\n &:focus:not(:active) {\n background-color: $button-focus-color-alt;\n }\n }\n}\n\ninput.mdl-button[type=\"submit\"] {\n -webkit-appearance:none;\n}\n\n // Raised buttons\n .mdl-button--raised {\n background: $button-primary-color;\n @include shadow-2dp();\n\n &:active {\n @include shadow-4dp();\n background-color: $button-active-color;\n }\n\n &:focus:not(:active) {\n @include focus-shadow();\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n background: $button-primary-color-alt;\n color: $button-secondary-color-alt;\n\n &:hover {\n background-color: $button-hover-color-alt;\n }\n\n &:active {\n background-color: $button-active-color-alt;\n }\n\n &:focus:not(:active) {\n background-color: $button-active-color-alt;\n }\n\n & .mdl-ripple {\n background: $button-ripple-color-alt;\n }\n }\n }\n\n\n // FABs\n .mdl-button--fab {\n border-radius: 50%;\n font-size: $button-fab-font-size;\n height: $button-fab-size;\n margin: auto;\n min-width: $button-fab-size;\n width: $button-fab-size;\n padding: 0;\n overflow: hidden;\n background: $button-primary-color;\n box-shadow: 0 1px 1.5px 0 rgba(0,0,0,0.12), 0 1px 1px 0 rgba(0,0,0,0.24);\n position: relative;\n line-height: normal;\n\n & .material-icons {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);\n line-height: $button-fab-font-size;\n width: $button-fab-font-size;\n }\n\n &.mdl-button--mini-fab {\n height: $button-fab-size-mini;\n min-width: $button-fab-size-mini;\n width: $button-fab-size-mini;\n }\n\n & .mdl-button__ripple-container {\n border-radius: 50%;\n // Fixes clipping bug in Safari.\n -webkit-mask-image: -webkit-radial-gradient(circle, white, black);\n }\n\n &:active {\n @include shadow-4dp();\n background-color: $button-active-color;\n }\n\n &:focus:not(:active) {\n @include focus-shadow();\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n background: $button-fab-color-alt;\n color: $button-fab-text-color-alt;\n\n &:hover {\n background-color: $button-fab-hover-color-alt;\n }\n\n &:focus:not(:active) {\n background-color: $button-fab-active-color-alt;\n }\n\n &:active {\n background-color: $button-fab-active-color-alt;\n }\n\n & .mdl-ripple {\n background: $button-fab-ripple-color-alt;\n }\n }\n }\n\n\n // Icon buttons\n .mdl-button--icon {\n border-radius: 50%;\n font-size: $button-fab-font-size;\n height: $button-icon-size;\n margin-left: 0;\n margin-right: 0;\n min-width: $button-icon-size;\n width: $button-icon-size;\n padding: 0;\n overflow: hidden;\n color: inherit;\n line-height: normal;\n\n & .material-icons {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);\n line-height: $button-fab-font-size;\n width: $button-fab-font-size;\n }\n\n &.mdl-button--mini-icon {\n height: $button-icon-size-mini;\n min-width: $button-icon-size-mini;\n width: $button-icon-size-mini;\n\n & .material-icons {\n top: ($button-icon-size-mini - $button-fab-font-size) / 2;\n left: ($button-icon-size-mini - $button-fab-font-size) / 2;\n }\n }\n\n & .mdl-button__ripple-container {\n border-radius: 50%;\n // Fixes clipping bug in Safari.\n -webkit-mask-image: -webkit-radial-gradient(circle, white, black);\n }\n }\n\n\n // Ripples\n .mdl-button__ripple-container {\n display: block;\n height: 100%;\n left: 0px;\n position: absolute;\n top: 0px;\n width: 100%;\n z-index: 0;\n overflow: hidden;\n\n .mdl-button[disabled] & .mdl-ripple,\n .mdl-button.mdl-button--disabled & .mdl-ripple {\n background-color: transparent;\n }\n }\n\n// Colorized buttons\n\n.mdl-button--primary.mdl-button--primary {\n color: $button-primary-color-alt;\n & .mdl-ripple {\n background: $button-secondary-color-alt;\n }\n &.mdl-button--raised, &.mdl-button--fab {\n color: $button-secondary-color-alt;\n background-color: $button-primary-color-alt;\n }\n}\n\n.mdl-button--accent.mdl-button--accent {\n color: $button-fab-color-alt;\n & .mdl-ripple {\n background: $button-fab-text-color-alt;\n }\n &.mdl-button--raised, &.mdl-button--fab {\n color: $button-fab-text-color-alt;\n background-color: $button-fab-color-alt;\n }\n}\n\n// Disabled buttons\n\n.mdl-button {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n color: $button-secondary-color-disabled;\n cursor: default;\n background-color: transparent;\n }\n\n &--fab {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n background-color: $button-primary-color-disabled;\n color: $button-secondary-color-disabled;\n }\n }\n\n &--raised {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n background-color: $button-primary-color-disabled;\n color: $button-secondary-color-disabled;\n box-shadow: none;\n }\n }\n &--colored {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n color: $button-secondary-color-disabled;\n }\n }\n}\n\n// Align icons inside buttons with text\n.mdl-button .material-icons {\n vertical-align: middle;\n}\n","// SIMPLE GRID - SASS/SCSS\n\n\n// fonts\n$font-weight-light: 300;\n$font-weight-regular: 400;\n$font-weight-heavy: 700;\n\n// colors\n$dark-grey: #333447;\n$dark-gray: #333447; // for the Americans\n\n\n.font-light {\n font-weight: $font-weight-light;\n}\n\n.font-regular {\n font-weight: $font-weight-regular;\n}\n\n.font-heavy {\n font-weight: $font-weight-heavy;\n}\n\n// utility\n\n.left {\n text-align: left;\n}\n\n.right {\n text-align: right;\n}\n\n.center {\n text-align: center;\n margin-left: auto;\n margin-right: auto;\n}\n\n.justify {\n text-align: justify;\n}\n\n.hidden-sm {\n display: none;\n}\n\n// grid\n\n$width: 98%;\n$gutter: 2%;\n$breakpoint-small: 33.75em; // 540px\n$breakpoint-med: 45em; // 720px\n$breakpoint-large: 60em; // 960px\n\n.container {\n width: 100%;\n margin-left: auto;\n margin-right: auto;\n\n @media only screen and (min-width: $breakpoint-small) {\n width: 80%;\n }\n\n @media only screen and (min-width: $breakpoint-large) {\n width: 75%;\n max-width: 60rem;\n }\n}\n\n.row {\n position: relative;\n width: 100%;\n}\n\n.row [class^=\"col\"] {\n float: left;\n margin: 0.5rem 1%;\n min-height: 0.125rem;\n}\n\n.row::after {\n content: \"\";\n display: table;\n clear: both;\n}\n\n.col-1,\n.col-2,\n.col-3,\n.col-4,\n.col-5,\n.col-6,\n.col-7,\n.col-8,\n.col-9,\n.col-10,\n.col-11,\n.col-12 {\n width: $width;\n}\n\n.col-1-sm {\n width: ($width / 12) - ($gutter * 11 / 12);\n}\n\n.col-2-sm {\n width: ($width / 6) - ($gutter * 10 / 12);\n}\n\n.col-3-sm {\n width: ($width / 4) - ($gutter * 9 / 12);\n}\n\n.col-4-sm {\n width: ($width / 3) - ($gutter * 8 / 12);\n}\n\n.col-5-sm {\n width: ($width / (12 / 5)) - ($gutter * 7 / 12);\n}\n\n.col-6-sm {\n width: ($width / 2) - ($gutter * 6 / 12);\n}\n\n.col-7-sm {\n width: ($width / (12 / 7)) - ($gutter * 5 / 12);\n}\n\n.col-8-sm {\n width: ($width / (12 / 8)) - ($gutter * 4 / 12);\n}\n\n.col-9-sm {\n width: ($width / (12 / 9)) - ($gutter * 3 / 12);\n}\n\n.col-10-sm {\n width: ($width / (12 / 10)) - ($gutter * 2 / 12);\n}\n\n.col-11-sm {\n width: ($width / (12 / 11)) - ($gutter * 1 / 12);\n}\n\n.col-12-sm {\n width: $width;\n}\n\n@media only screen and (min-width: $breakpoint-med) {\n .col-1 {\n width: ($width / 12) - ($gutter * 11 / 12);\n }\n .col-2 {\n width: ($width / 6) - ($gutter * 10 / 12);\n }\n .col-3 {\n width: ($width / 4) - ($gutter * 9 / 12);\n }\n .col-4 {\n width: ($width / 3) - ($gutter * 8 / 12);\n }\n .col-5 {\n width: ($width / (12 / 5)) - ($gutter * 7 / 12);\n }\n .col-6 {\n width: ($width / 2) - ($gutter * 6 / 12);\n }\n .col-7 {\n width: ($width / (12 / 7)) - ($gutter * 5 / 12);\n }\n .col-8 {\n width: ($width / (12 / 8)) - ($gutter * 4 / 12);\n }\n .col-9 {\n width: ($width / (12 / 9)) - ($gutter * 3 / 12);\n }\n .col-10 {\n width: ($width / (12 / 10)) - ($gutter * 2 / 12);\n }\n .col-11 {\n width: ($width / (12 / 11)) - ($gutter * 1 / 12);\n }\n .col-12 {\n width: $width;\n }\n\n .hidden-sm {\n display: block;\n }\n}\n\n.row {\n display: -webkit-box;\n display: -webkit-flex;\n display: -ms-flexbox;\n display: flex;\n flex-wrap: wrap;\n}\n\n.row > [class*='col-'] {\n display: flex;\n flex-direction: column;\n}\n","\n/*\nMaterial Icons\n*/\n\n.material-icons {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px; /* Preferred icon size */\n display: inline-block;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n word-wrap: normal;\n white-space: nowrap;\n direction: ltr;\n \n /* Support for all WebKit browsers. */\n -webkit-font-smoothing: antialiased;\n /* Support for Safari and Chrome. */\n text-rendering: optimizeLegibility;\n \n /* Support for Firefox. */\n -moz-osx-font-smoothing: grayscale;\n \n /* Support for IE. */\n font-feature-settings: 'liga';\n }","html {\n font-size: $font_size;\n}\n\nbody {\n display: block !important;\n background-color: $background_color;\n font-size: 1rem;\n line-height: 1.5rem;\n font-family: $body_font_family;\n}\n\n.mdl-layout__content:focus {\n outline: none;\n }\n\nh1, h2, h3, h4, h5, h6, blockquote, span.mdl-layout-title,\na.download > code.download {\n font-family: $body_font_family;\n}\n\nh1, h2, h3, h4, h5, h6, .toc-backref, .contents, .toctree-wrapper, .contents a, .toctree-wrapper a, .globaltoc a.current {\n color: $color-mxnet !important;\n}\n\na {\n text-decoration: none;\n}\n\n.page-content {\n font-size: 1rem;\n p, ul, ol, dl, dd, dt, table, th, td {\n font-size: 1rem;\n }\n}\n\n.brand {\n color: inherit;\n text-decoration: none;\n}\n\n.section {\n overflow-x: auto;\n}\n\n\n/*\n * Figure Directive Styles\n */\n img {\n max-width: 100%;\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n\ndiv.figure {\n p.caption {\n text-align: center;\n margin-top: .75rem;\n\n span.caption-number {\n font-style: normal;\n }\n .caption-number::after {\n content: \"\\00a0\";\n }\n }\n}\n\n.svg-icon {\n width: 16px;\n height: 16px;\n display: inline-block;\n fill: $grey-color-light;\n padding-right: 5px;\n padding-top: 4px;\n vertical-align: text-top;\n}\n\n/*\n * Download Link Styles\n */\na.download > i.material-icons {\n position: relative;\n top: 5px;\n}\n\na.download {\n text-decoration: none;\n}\n\n%clearfix:after {\n content: \"\";\n display: table;\n clear: both;\n}\n\n.wrapper {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));\n max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));\n margin-right: auto;\n margin-left: auto;\n padding-right: calc(#{$spacing-unit}+15px);\n padding-left: $spacing-unit;\n @extend %clearfix;\n\n @media screen and (max-width: $on-laptop) {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));\n max-width: calc(#{$content-width} - (#{$spacing-unit}));\n padding-right: $spacing-unit / 2;\n padding-left: $spacing-unit / 2;\n }\n}\n\n","/*\nVariables\n*/\n$font_size: 16px;\n\n$background_color: #fafafa;\n$code_background: rgba(0,0,0,.05);\n\n$code_font_family: \"Menlo\", \"DejaVu Sans Mono\", \"Liberation Mono\", \"Consolas\", \"Ubuntu Mono\", \"Courier New\", \"andale mono\", \"lucida console\", monospace !default;\n$body_font_family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\" !default;\n$base-font-size: 17px !default;\n\n$xl-breakpoint: 1795px;\n$lg-breakpoint: 1200px;\n$md-breakpoint: 992px;\n$sm-breakpoint: 768px;\n$xs-breakpoint: 576px;\n\n$color-primary: $palette-blue-500;\n$color-primary-dark: $palette-blue-700 !default;\n$color-accent: $palette-deep-orange-A200 !default;\n$color-primary-contrast: $color-white !default;\n$color-accent-contrast: $color-white !default;\n\n\n$base-line-height: 1.5 !default;\n$spacing-unit: 30px !default;\n\n$color-mxnet: rgb(4,140,204);\n$color-mxnet-dark: rgb(4,60,110);\n$grey-color: #828282 !default;\n$grey-color-light: lighten($grey-color, 45%) !default;\n$grey-color-dark: darken($grey-color, 25%) !default;\n\n$table-text-align: left !default;\n\n// Width of the content area\n$content-width: 1150px !default;\n\n$on-palm: 600px !default;\n$on-palm: 900px !default;\n$on-laptop: 1024px !default;","/**\n * Layout Styles\n */\n $layout: (\n document: (\n xl: (\n width: 1400px,\n )\n ),\n drawer-container: (\n width: $layout-drawer-width,\n ),\n side-doc-outline: (\n width: 230px,\n ),\n page-content: (\n md: (\n width: 90%,\n padding: 0 5%\n ),\n lg: (\n width: calc( 90% - 230px ),\n padding: 0 5%\n )\n )\n);\n\n.mdl-layout {\n margin-top: 76px;\n}\n\n\n.document {\n width: 100%;\n margin: 0 auto;\n display: flex;\n\n @media (min-width: $xl-breakpoint) {\n width: map-get(map-get(map-get($layout, document), xl), width);\n }\n .page-content {\n width: 100%;\n margin: 0 auto;\n padding: 0 12px;\n\n @media (min-width: $md-breakpoint) {\n width: map-get(map-get(map-get($layout, page-content), md), width);\n padding: map-get(map-get(map-get($layout, page-content), md), padding);\n }\n\n @media (min-width: $lg-breakpoint) {\n width: map-get(map-get(map-get($layout, page-content), lg), width);\n padding: map-get(map-get(map-get($layout, page-content), lg), padding);\n }\n }\n\n .side-doc-outline {\n width: map-get(map-get($layout, side-doc-outline), width);\n\n @media (max-width: $lg-breakpoint - 1) {\n display: none;\n } \n &--content {\n position: fixed;\n overflow-x: auto;\n overflow-y: auto;\n width: inherit;\n &::-webkit-scrollbar {\n width: 6px;\n }\n \n &::-webkit-scrollbar-track {\n border-radius: 6px;\n }\n \n &::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, .3);\n border-radius: 6px;\n box-shadow:0 0 0 1px rgba(255, 255, 255, .3);\n }\n }\n }\n\n}","@keyframes float-in {\n 0% {\n transform: translateY(0.5rem);\n opacity: 0;\n }\n\t100% {\n\t\ttransform: translateY(0);\n\t\topacity: 1;\n\t}\n}\n\n@keyframes float-out {\n 0% {\n transform: translateY(0);\n opacity: 1;\n }\n\t100% {\n\t\ttransform: translateY(0.5rem);\n\t\topacity: 0;\n\t}\n}\n\n.page-content {\n .headerlink {\n display: inline-block;\n text-decoration: none;\n margin-left: 0.8rem;\n color: inherit;\n opacity: 0;\n &:hover {\n animation: float-in 0.2s $animation-curve-fast-out-slow-in 0s forwards;\n }\n }\n\n h1, h2, h3, h4, h5, h6 {\n .toc-backref {\n text-decoration: none;\n }\n &:hover {\n .headerlink {\n animation: float-in 0.2s $animation-curve-fast-out-slow-in 0s forwards;\n }\n }\n }\n\n h1 {\n font-size: 2rem;\n line-height: 2.25rem;\n }\n\n h2 {\n font-size: 1.75rem;\n line-height: 2rem;\n padding-top: 1.5rem;\n margin-top: 0;\n margin-bottom: 1rem;\n }\n\n h3 {\n font-size: 1.5rem;\n line-height: 1.75rem;\n padding-top: 1rem;\n margin-top: 0px;\n margin-bottom: .75rem;\n }\n\n h4 {\n font-size: 1.25rem;\n line-height: 1.5rem;\n padding-top: .75rem;\n margin-top: 0px;\n margin-bottom: .5rem;\n }\n\n div.page-content h5 {\n font-size: 1.1rem;\n line-height: 1.5rem;\n padding-top: 2rem;\n margin-top: 0px;\n margin-bottom: 1rem;\n }\n\n div.page-content h6 {\n font-size: 1rem;\n line-height: 1.5rem;\n padding-top: 2rem;\n margin-top: 0px;\n margin-bottom: 1rem;\n }\n\n\n}\n","\n/*\n * Admonition Styles\n */\n $admonitions: (\n hint: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"help_outline\"\n ),\n note: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"info_outline\"\n ),\n seealso: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"search\"\n ),\n warning: (\n font-color: rgb(255, 193, 7),\n background-color: rgba(255, 193, 7, 0.1),\n icon-content: \"warning\"\n ),\n attention: (\n font-color: rgb(255, 193, 7),\n background-color: rgba(255, 193, 7, 0.1),\n icon-content: \"warning\"\n ),\n tip: (\n font-color: rgb(139, 195, 74),\n background-color: rgba(139, 195, 74, 0.1),\n icon-content: \"lightbulb_outline\"\n ),\n important: (\n font-color: rgb(139, 195, 74),\n background-color: rgba(139, 195, 74, 0.1),\n icon-content: \"check_circle\"\n ),\n error: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n ),\n caution: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n ),\n danger: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n )\n);\n\n @mixin admonition-style($type) {\n border-left: solid 4px map-get(map-get($admonitions, $type), font-color);\n background-color: map-get(map-get($admonitions, $type), background-color);\n .admonition-title {\n font-size: 16px;\n font-weight: bold;\n color: map-get(map-get($admonitions, $type), font-color);\n\n margin-top: 4px;\n margin-bottom: 8px;\n &::before {\n @extend .material-icons;\n position: relative;\n margin-right: 5px;\n top: 3px;\n content: map-get(map-get($admonitions, $type), icon-content);\n font-size: 18px;\n }\n }\n}\n\n.admonition {\n @extend .mdl-shadow--2dp;\n\n padding: 12px 20px;\n margin-top: 10px;\n margin-bottom: 10px;\n p.last {\n margin: 16px;\n }\n .admonition-title {\n font-size: 16px;\n font-weight: bold;\n color: #555;\n text-transform: uppercase;\n margin-top: 7px;\n }\n\n @each $type in (note, seealso, hint, warning, attention, tip, important, error, caution, danger) {\n &.#{$type} {\n @include admonition-style($type);\n }\n }\n}\n",".page-content {\n .highlight {\n margin: 1px 0;\n pre {\n background: $code_background;\n color: rgba(0,0,0,.87);\n font-family: $code_font_family;\n padding: 0.75rem;\n overflow: auto;\n overflow-y: hidden;\n .o, .nd {\n color: rgba(0,0,0,.87);\n }\n }\n }\n\n div.highlight-console div.highlight {\n background: none;\n }\n\n // for jupyter notebook output cell\n .output {\n .highlight {\n pre {\n color: rgba(0,0,0,.87);\n background: $background_color;\n border-width: 1px;\n border-color: #999;\n border-style: solid;\n padding: 0.75rem;\n }\n }\n }\n\n .code, code:not(.download) {\n margin: 0 0;\n font-family: $code_font_family;\n border-radius: 2px;\n span.pre {\n font-family: $code_font_family;\n }\n }\n\n .viewcode-link {\n padding-left: 2em;\n font-size: 80%;\n }\n\n .rubric, .method > dt, .function > dt, .class > dt {\n display: table;\n margin: 10px 0;\n font-size: 100%;\n line-height: normal;\n background: #e7f2fa;\n color: #2B98F0;\n border-top: solid 3px #55ADF3;\n padding: 10px;\n position: relative;\n .descname, .descclassname {\n color: rgba(0,0,0,.87);\n background: #e7f2fa;\n padding: 3px;\n }\n em {\n padding: 0 2px;\n }\n }\n\n\n .rubric {\n margin: 30px 0 10px 0;\n }\n\n\n .field-body {\n padding-left: 40px;\n ul {\n padding: 0 0 0 16px;\n margin: 0;\n }\n }\n\n // .docutils > dt {\n // padding: 6px;\n // display: table;\n // margin-bottom: 6px;\n // border: none;\n // border-left: solid 3px #ccc;\n // background: #f0f0f0;\n // color: #555;\n // }\n\n .seealso .docutils > dt {\n float: left;\n clear: left;\n padding: 0 6px;\n }\n\n .seealso .docutils > dd {\n padding-left: 6em;\n }\n .nblast {\n padding-bottom: 1em;\n }\n\n pre {\n font-size: 90%;\n background: #eee;\n color: #455A64;\n padding: 16px 32px;\n width: auto;\n border-radius: 4px;\n word-wrap: break-word;\n\n &:hover {\n @extend .mdl-shadow--2dp;\n\n &:before {\n font-family: $body_font_family;\n padding: 0 0.5rem;\n content: attr(click-to-copy);\n color: rgba(0, 0, 0, 0.5);\n border-radius: 4px;\n position: relative;\n float: right;\n top: -0.5rem;\n right: -0.5rem;\n background: rgb(200, 200, 200);\n font-size: 0.8rem;\n cursor: pointer;\n }\n }\n }\n}\n","/*\n * Quotation Block Styles\n */\n .page-content {\n blockquote {\n font-size: 1rem;\n padding: 0 1rem;\n border-left: 3px solid $code_background;\n\n &:after {\n content: \"\" !important;\n margin-left: 0;\n }\n &:before {\n content: \"\" !important;\n }\n }\n }\n",".page-content {\n table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) {\n @extend .mdl-data-table;\n @extend .mdl-shadow--2dp;\n\n margin: 1.5rem 0;\n table-layout: fixed;\n max-width: 100%;\n min-width: 70%;\n\n th, td {\n @extend .mdl-data-table__cell--non-numeric;\n white-space: normal;\n overflow-wrap: break-word;\n }\n\n caption {\n font-size: $font_size;\n margin: 1rem 0 0.8rem 0;\n white-space: normal;\n .caption-number {\n font-style: normal;\n }\n .caption-number::after {\n content: \"\\00a0\";\n }\n }\n\n }\n}\n",".globaltoc {\n \n .caption, .toc {\n display: none;\n }\n\n ul {\n\n list-style-type: none;\n padding: 0;\n margin: 0;\n\n li {\n min-height: 18px;\n .link-wrapper {\n display: flex;\n justify-content: space-between;\n > a {\n padding: 4px 0;\n display: block;\n width: 100%;\n font-size: 1rem;\n text-decoration: none;\n color: $layout-drawer-navigation-color;\n &.current {\n font-weight: bold;\n }\n }\n }\n }\n }\n\n .nav-toggle {\n padding: 0;\n float: right;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n > a {\n padding: 0;\n margin-left: 0;\n margin-right: 4px;\n cursor: pointer;\n > i {\n font-size: 18px;\n }\n }\n &.show {\n transform: rotateZ(180deg);\n > a {\n margin-right: 0;\n margin-left: 4px;\n }\n }\n }\n\n nav {\n > ul > li > span.link-wrapper {\n padding-left: 8px;\n }\n > ul > li > ul > li > span.link-wrapper {\n padding-left: 16px;\n }\n > ul > li > ul > li > ul > li > span.link-wrapper {\n padding-left: 24px;\n }\n > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 32px;\n }\n > ul > li > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 40px;\n }\n > ul > li > ul > li > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 48px;\n }\n }\n}\n",".localtoc {\n font-size: 0.75rem;\n padding-top: 1rem;\n\n .caption {\n padding-left: 12px;\n &-text {\n font-size: 0.9rem;\n font-weight: 700;\n }\n }\n\n > ul > li > a {\n display: none;\n }\n\n ul {\n padding: 0;\n list-style-type: none;\n }\n\n li {\n padding-left: 6px;\n }\n\n a {\n display: block;\n text-decoration: none;\n color: inherit;\n margin-top: 8px;\n padding-left: 8px;\n line-height: 1.1rem;\n \n &.current {\n padding-left: 5px;\n border-left: 3px solid;\n font-weight: bold;\n }\n }\n}","/*\r\n * Toctree and Contents Directive Styles\r\n */\r\n .toctree-wrapper,\r\n .contents.topic {\r\n border-left: 5px solid;\r\n }\r\n\r\n .toctree-wrapper > p.caption,\r\n .contents.topic > p.topic-title {\r\n color: rgb(117, 117, 117);\r\n font-size: 1rem;\r\n padding-left: 14px;\r\n }\r\n\r\n .toctree-wrapper ul,\r\n .contents.topic ul{\r\n padding-left: 14px;\r\n list-style: none;\r\n line-height: 30px;\r\n }\r\n\r\n .toctree-wrapper a,\r\n .contents.topic a {\r\n font-size: 1.2rem;\r\n text-decoration: none;\r\n .pre {\r\n font-size: 1rem;\r\n }\r\n }\r\n\r\n .toctree-wrapper > ul > li > a,\r\n .contents.topic > ul > li > a {\r\n font-size: 1.3rem;\r\n .pre {\r\n font-size: 1.1rem;\r\n }\r\n }\r\n",".page-content {\n ul {\n li {\n margin: .3rem 0;\n p {\n margin: 0;\n }\n }\n }\n .option-list {\n .option {\n font-family: $code_font_family;\n }\n td {\n padding: 0.5rem;\n border: none;\n }\n }\n}\n","/*\r\n * Drawer Styles\r\n */\r\n.mdl-layout {\r\n &__drawer {\r\n background-color: #fff;\r\n\r\n &::-webkit-scrollbar {\r\n width: 6px;\r\n }\r\n\r\n &::-webkit-scrollbar-track {\r\n border-radius: 6px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background-color: rgba(0, 0, 0, .3);\r\n border-radius: 6px;\r\n box-shadow:0 0 0 1px rgba(255, 255, 255, .3);\r\n }\r\n\r\n > .mdl-layout-title {\r\n font-weight: bold;\r\n text-align: right;\r\n margin: 0;\r\n padding: 0;\r\n line-height: 32px;\r\n border-bottom: 1px solid rgba(0,0,0,.1);\r\n min-height: 64px;\r\n .title {\r\n color: inherit;\r\n display: block;\r\n height: 100%;\r\n width: 100%;\r\n text-decoration: none;\r\n > img.logo {\r\n width: 100%;\r\n margin: 0;\r\n padding: 0;\r\n }\r\n\r\n &-text {\r\n font-weight: bold;\r\n text-align: right;\r\n padding: 0 10px;\r\n margin: 16px 0 8px 0;\r\n line-height: 32px;\r\n font-family: $body_font_family;\r\n color: inherit;\r\n display: block;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","/*\r\n * Header Styles\r\n */\r\n\r\nnav.breadcrumb {\r\n > a.mdl-navigation__link {\r\n padding: 0 8px;\r\n font-size: 18px;\r\n }\r\n @media (max-width: $lg-breakpoint - 1) {\r\n width: calc( 100% - 64px );\r\n a.mdl-navigation__link.is-active {\r\n overflow-x: hidden;\r\n width: 100%;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n }\r\n a.mdl-navigation__link:not(.is-active),\r\n i.material-icons {\r\n display: none;\r\n }\r\n }\r\n}\r\n\r\ndiv.mdl-layout__header {\r\n margin-top: 77px;\r\n}\r\n\r\n.mdl-layout__drawer-button {\r\n top: 13px !important;\r\n}\r\n\r\ndiv.mdl-layout__header-row.header-links {\r\n background: rgba(255,255,255,0.2);\r\n width: 100%;\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n\r\n a.mdl-navigation__link {\r\n font-size: 1rem;\r\n i {\r\n font-size: 1.2rem;\r\n margin: 0 8px;\r\n position: relative;\r\n bottom: -0.1rem;\r\n }\r\n };\r\n\r\n a.mdl-navigation__link:hover {\r\n background-color: unquote(\"rgb(#{$color-primary})\");\r\n color: #eeeeee;\r\n };\r\n a.mdl-navigation__link[href=\"#\"] {\r\n background-color: unquote(\"rgb(#{$color-primary})\");\r\n opacity: 1;\r\n color: #ffffff;\r\n };\r\n}\r\n\r\n/* mxnet-header */\r\n\r\n\r\n.site-title {\r\n font-weight: 300 !important;\r\n line-height: 57px;\r\n letter-spacing: -1px;\r\n margin-bottom: 0;\r\n float: left;\r\n color: white;\r\n\r\n &,\r\n &:visited {\r\n color: $grey-color-dark;\r\n }\r\n}\r\n\r\n\r\n.site-header {\r\n position: fixed;\r\n top: 0;\r\n width: 100%;\r\n min-height: 55px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\r\n background-color: $color-mxnet;\r\n z-index: 10;\r\n font-weight: 300;\r\n font-size: 17px;\r\n border-bottom: 1px solid white;\r\n}\r\n\r\n.site-header-logo {\r\n width: 120px;\r\n display: initial;\r\n}\r\n\r\n.site-nav {\r\n float: right;\r\n line-height: 57px;\r\n\r\n .nav-trigger {\r\n display: none;\r\n }\r\n\r\n .menu-icon {\r\n display: none;\r\n }\r\n\r\n .page-link {\r\n color: white;\r\n line-height: 1.5;\r\n font-weight: 300;\r\n // Gaps between nav items, but not on the last one\r\n &:not(:last-child) {\r\n margin-right: 40px;\r\n }\r\n\r\n &:hover {\r\n color: white;\r\n text-shadow: -0.06ex 0 white, 0.06ex 0 white;\r\n }\r\n }\r\n\r\n .page-link.page-current {\r\n color: white;\r\n text-decoration: underline;\r\n }\r\n\r\n @media screen and (max-width: $on-laptop) {\r\n position: absolute;\r\n top: 9px;\r\n right: 15px;\r\n background-color: rgb(23,141,201);\r\n border-radius: 2px;\r\n text-align: right;\r\n\r\n label[for=\"nav-trigger\"] {\r\n display: block;\r\n float: right;\r\n width: 36px;\r\n height: 36px;\r\n z-index: 2;\r\n cursor: pointer;\r\n }\r\n\r\n .menu-icon {\r\n display: block;\r\n float: right;\r\n width: 36px;\r\n height: 26px;\r\n line-height: 0;\r\n padding-top: 20px;\r\n text-align: center;\r\n\r\n > svg {\r\n fill: white;\r\n }\r\n }\r\n\r\n input ~ .trigger {\r\n clear: both;\r\n display: none;\r\n }\r\n\r\n input:checked ~ .trigger {\r\n display: block;\r\n padding-bottom: 5px;\r\n }\r\n\r\n .page-link {\r\n padding: 5px 10px;\r\n display: block;\r\n\r\n &:not(:last-child) {\r\n margin-right: 0;\r\n }\r\n\r\n margin-left: 20px;\r\n }\r\n }\r\n}","/*\r\n * Footer Styles\r\n */\r\nfooter.mdl-mini-footer {\r\n background-color: #212121;\r\n > div.mdl-mini-footer__left-section {\r\n margin-bottom: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n .mdl-logo {\r\n font-size: 1.1rem;\r\n }\r\n ul {\r\n @extend .mdl-mini-footer__link-list;\r\n }\r\n }\r\n > div.mdl-mini-footer__right-section {\r\n font-size: 0.9rem;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-end;\r\n\r\n a {\r\n color: inherit;\r\n font-weight: bold;\r\n text-decoration: none;\r\n }\r\n }\r\n p.caption {\r\n display: none;\r\n }\r\n}\r\n\r\n/*\r\n * Pagenation Block Styles\r\n */\r\n .pagenation {\r\n width: 100%;\r\n margin-top: 80px;\r\n height: 92px;\r\n background-color: #424242;\r\n display: flex;\r\n\r\n .button-common {\r\n text-transform: none;\r\n padding: 0;\r\n height: 92px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n color: #ffffff;\r\n }\r\n #button-prev {\r\n @extend .button-common;\r\n margin-right: auto;\r\n .pagenation-text {\r\n text-align: left;\r\n }\r\n \r\n }\r\n #button-next {\r\n @extend .button-common;\r\n margin-left: auto;\r\n flex-direction: row-reverse;\r\n .pagenation-text {\r\n text-align: right;\r\n }\r\n }\r\n\r\n &-arrow {\r\n &-L {\r\n margin-right: 20px;\r\n }\r\n &-R {\r\n margin-left: 20px;\r\n }\r\n }\r\n\r\n &-text {\r\n line-height: 30px;\r\n font-size: 20px;\r\n }\r\n\r\n &-direction {\r\n opacity: 0.7;\r\n font-size: 18px;\r\n }\r\n @media screen and (max-width: 1024px) {\r\n #button-prev {\r\n width: 20%;\r\n }\r\n \r\n #button-next {\r\n width: 80%;\r\n }\r\n \r\n #button-prev .pagenation-text {\r\n display: none;\r\n }\r\n }\r\n @media screen and (min-width: 1025px) {\r\n #button-prev,\r\n #button-next {\r\n width: 50%;\r\n }\r\n \r\n #button-prev .pagenation-text {\r\n display: block;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Site footer\r\n */\r\n.site-footer {\r\n border-top: 1px solid $grey-color-light;\r\n padding: $spacing-unit 0;\r\n background-color: #424242;\r\n .footer-category-title {\r\n color: $color-mxnet;\r\n }\r\n a {\r\n color: $grey-color-light !important;\r\n\r\n &:visited {\r\n color: $grey-color-light !important;\r\n }\r\n }\r\n\r\n}\r\n\r\n.site-footer2 {\r\n background-color: #424242;\r\n padding-top: 40px;\r\n padding-bottom: 10px;\r\n}\r\n\r\n.footer-heading {\r\n margin-bottom: $spacing-unit / 2;\r\n}\r\n\r\n.contact-list,\r\n.social-media-list {\r\n list-style: none;\r\n margin-left: 0;\r\n}\r\n\r\n\r\n.footer-bottom-warning {\r\n font-size: 80%;\r\n color: white;\r\n float: left;\r\n}\r\n\r\n.footer-logo {\r\n width: 200px;\r\n margin-bottom: 30px;\r\n margin-top: 30px;\r\n}\r\n\r\n.footer-col {\r\n float: left;\r\n margin-bottom: $spacing-unit / 2;\r\n padding-left: $spacing-unit / 2;\r\n}\r\n\r\n.footer-text {\r\n color: $grey-color-light;\r\n}\r\n\r\n"," /*\r\n * Search Styles\r\n */\r\n#waterfall-exp::-webkit-input-placeholder {\r\n color: #ccc;\r\n}\r\n#waterfall-exp:-ms-input-placeholder {\r\n color: #ccc;\r\n}\r\n#waterfall-exp::-moz-placeholder {\r\n color: #ccc;\r\n}\r\n\r\nul.search span.highlighted {\r\n font-weight: bold;\r\n}\r\n\r\nul.search > li {\r\n margin-bottom: 24px;\r\n}\r\n\r\n#search-results {\r\n ul {\r\n list-style: none;\r\n padding: 0;\r\n li {\r\n > a {\r\n text-decoration: none;\r\n font-size: 1.2rem;\r\n }\r\n }\r\n }\r\n}\r\n","a.download {\n &:before {\n @extend .material-icons;\n content: \"file_download\";\n position: relative;\n top: 5px;\n margin-right: 5px;\n }\n}\n\nbutton.download {\n position: sticky;\n margin-left: 1em;\n}\n",".mdl-card {\n margin: 1em 1.5em 1em 0;\n display: inline-block;\n width: 250px;\n min-height: 140px;\n padding: 18px;\n}\n.mdl-card:hover {\n box-shadow: 0 10px 20px rgba(0,0,0,0.25), 0 6px 6px rgba(0,0,0,0.22);\n color: #000;\n cursor: pointer;\n}\n.mdl-card__title {\n padding: 0 0 1em 0;\n font-size: 18px;\n color: #444;\n}\n\n.mdl-card__supporting-text {\n line-height: 1.5rem;\n padding: 0px;\n width: 100%;\n}\n\n.head-card.mdl-card {\n width: auto;\n display: block;\n max-width: 800px;\n padding: 24px;\n}\n\n.head-card > .mdl-card__title {\n padding-bottom: 0px;\n height: 60px;\n font-weight: 700;\n text-transform: uppercase;\n}\n.head-card > .mdl-card__menu {\n color: #fff;\n}\n.head-card > .mdl-card__actions {\n padding: 0;\n}\n.cards {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../../node_modules/material-design-lite/src/shadow/_shadow.scss","../../node_modules/material-design-lite/src/_mixins.scss","../../node_modules/material-design-lite/src/data-table/_data-table.scss","../../node_modules/material-design-lite/src/_variables.scss","../../node_modules/material-design-lite/src/footer/_mini_footer.scss","../../node_modules/material-design-lite/src/card/_card.scss","../../node_modules/material-design-lite/src/button/_button.scss","../scss/grid/_simplegrid.scss","../scss/fonts/_material-icons.scss","../scss/_root.scss","../scss/_variables.scss","../scss/layout/_layout.scss","../scss/headerings/_headerings.scss","../scss/admonitions/_admonitions.scss","../scss/code/_code.scss","../scss/blockquote/_blockquote.scss","../scss/tables/_tables.scss","../scss/toc/_globaltoc.scss","../scss/toc/_localtoc.scss","../scss/toc/_toctree.scss","../scss/lists/_lists.scss","../scss/drawer/_drawer.scss","../scss/header/_header.scss","../scss/footer/_footer.scss","../scss/search/_search.scss","../scss/downloadlink/_downloadlink.scss","../scss/card/_card.scss"],"names":[],"mappings":"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","file":"sphinx_materialdesign_theme.css","sourceRoot":"../../src/js","sourcesContent":["/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n.mdl-shadow--2dp {\n @include shadow-2dp();\n}\n\n.mdl-shadow--3dp {\n @include shadow-3dp();\n}\n\n.mdl-shadow--4dp {\n @include shadow-4dp();\n}\n\n.mdl-shadow--6dp {\n @include shadow-6dp();\n}\n\n.mdl-shadow--8dp {\n @include shadow-8dp();\n}\n\n.mdl-shadow--16dp {\n @include shadow-16dp();\n}\n\n.mdl-shadow--24dp {\n @include shadow-24dp();\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Typography */\n\n@mixin typo-preferred-font($usePreferred: true) {\n @if $usePreferred {\n font-family: $preferred_font;\n }\n}\n\n@mixin typo-display-4($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 112px;\n font-weight: 300;\n line-height: 1;\n letter-spacing: -0.04em;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-3($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 56px;\n font-weight: 400;\n line-height: 1.35;\n letter-spacing: -0.02em;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-2($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 45px;\n font-weight: 400;\n line-height: 48px;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-display-1($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 34px;\n font-weight: 400;\n line-height: 40px;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-headline($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 24px;\n font-weight: 400;\n line-height: 32px;\n -moz-osx-font-smoothing: grayscale;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-title($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 20px;\n font-weight: 500;\n line-height: 1;\n letter-spacing: 0.02em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-subhead($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 16px;\n font-weight: 400;\n line-height: 24px;\n letter-spacing: 0.04em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-subhead-2($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 16px;\n font-weight: 400;\n line-height: 28px;\n letter-spacing: 0.04em;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-body-2($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n @if $usePreferred {\n font-weight: 500;\n } @else {\n font-weight: bold;\n }\n line-height: 24px;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-body-1($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 400;\n line-height: 24px;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-caption($colorContrast: false, $usePreferred: false) {\n @include typo-preferred-font($usePreferred);\n font-size: 12px;\n font-weight: 400;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-blockquote($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n position: relative;\n font-size: 24px;\n font-weight: 300;\n font-style: italic;\n line-height: 1.35;\n letter-spacing: 0.08em;\n\n &:before {\n position: absolute;\n left: -0.5em;\n content: '“';\n }\n\n &:after {\n content: '”';\n margin-left: -0.05em;\n }\n\n @if $colorContrast {\n opacity: 0.54;\n }\n}\n\n@mixin typo-menu($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 500;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-button($colorContrast: false, $usePreferred: true) {\n @include typo-preferred-font($usePreferred);\n font-size: 14px;\n font-weight: 500;\n text-transform: uppercase;\n line-height: 1;\n letter-spacing: 0;\n\n @if $colorContrast {\n opacity: 0.87;\n }\n}\n\n@mixin typo-icon() {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px;\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n word-wrap: normal;\n font-feature-settings: 'liga';\n -webkit-font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* Shadows */\n\n// Focus shadow mixin.\n@mixin focus-shadow() {\n box-shadow: 0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);\n}\n\n@mixin shadow-2dp() {\n box-shadow: 0 2px 2px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 1px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),\n 0 1px 5px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);\n}\n@mixin shadow-3dp() {\n box-shadow: 0 3px 4px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 3px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),\n 0 1px 8px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);\n}\n@mixin shadow-4dp() {\n box-shadow: 0 4px 5px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 1px 10px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n@mixin shadow-6dp() {\n box-shadow: 0 6px 10px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 1px 18px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n@mixin shadow-8dp() {\n box-shadow: 0 8px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 3px 14px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n@mixin shadow-16dp() {\n box-shadow: 0 16px 24px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 6px 30px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n@mixin shadow-24dp() {\n box-shadow: 0 9px 46px 8px rgba(0, 0, 0, $shadow-key-penumbra-opacity),\n 0 11px 15px -7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),\n 0 24px 38px 3px rgba(0, 0, 0, $shadow-key-umbra-opacity);\n}\n\n/* Animations */\n\n@mixin material-animation-fast-out-slow-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-fast-out-slow-in;\n}\n\n@mixin material-animation-linear-out-slow-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-linear-out-slow-in;\n}\n\n@mixin material-animation-fast-out-linear-in($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-fast-out-linear-in;\n}\n\n@mixin material-animation-default($duration:0.2s) {\n transition-duration: $duration;\n transition-timing-function: $animation-curve-default;\n}\n\n/* Dialog */\n\n@mixin dialog-width($units:5) {\n @if(type_of($units) != 'number') {\n @error \"The unit given to dialog-width should be a number.\";\n }\n // 56dp is the base unit width for Dialogs.\n // With 5 units being the number of units for a mobile device.\n // https://goo.gl/sK2O5o\n width: $units * 56px;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n.mdl-data-table {\n position: relative;\n border: $data-table-dividers;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: $data-table-font-size;\n background-color: unquote(\"rgb(#{$color-white})\");\n\n thead {\n padding-bottom: 3px;\n\n .mdl-data-table__select {\n margin-top: 0;\n }\n }\n\n tbody {\n tr {\n position: relative;\n height: $data-table-row-height;\n @include material-animation-default(0.28s);\n transition-property: background-color;\n\n &.is-selected {\n background-color: $data-table-selection-color;\n }\n\n &:hover {\n background-color: $data-table-hover-color;\n }\n }\n }\n\n td, th {\n padding: 0 $data-table-column-padding 12px $data-table-column-padding;\n text-align: right;\n\n &:first-of-type {\n padding-left: 24px;\n }\n\n &:last-of-type {\n padding-right: 24px;\n }\n }\n\n td {\n position: relative;\n vertical-align: middle;\n height: $data-table-row-height;\n border-top: $data-table-dividers;\n border-bottom: $data-table-dividers;\n padding-top: $data-table-cell-top;\n box-sizing: border-box;\n\n .mdl-data-table__select {\n vertical-align: middle;\n }\n }\n\n th {\n position: relative;\n vertical-align: bottom;\n text-overflow: ellipsis;\n @include typo-body-2();\n height: $data-table-row-height;\n font-size: $data-table-header-font-size;\n color: $data-table-header-color;\n padding-bottom: 8px;\n box-sizing: border-box;\n\n &.mdl-data-table__header--sorted-ascending,\n &.mdl-data-table__header--sorted-descending {\n color: $data-table-header-sorted-color;\n &:before {\n @include typo-icon;\n font-size: $data-table-header-sort-icon-size;\n content: \"\\e5d8\";\n margin-right: 5px;\n vertical-align: sub;\n }\n &:hover {\n cursor: pointer;\n &:before {\n color: $data-table-header-sorted-icon-hover-color;\n }\n }\n }\n &.mdl-data-table__header--sorted-descending:before {\n content: \"\\e5db\";\n }\n }\n}\n\n.mdl-data-table__select {\n width: 16px;\n}\n\n.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric {\n text-align: left;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*------------------------------------*\\\n $CONTENTS\n\\*------------------------------------*/\n/**\n * STYLE GUIDE VARIABLES------------------Declarations of Sass variables\n * -----Typography\n * -----Colors\n * -----Textfield\n * -----Switch\n * -----Spinner\n * -----Radio\n * -----Menu\n * -----List\n * -----Layout\n * -----Icon toggles\n * -----Footer\n * -----Column\n * -----Checkbox\n * -----Card\n * -----Button\n * -----Animation\n * -----Progress\n * -----Badge\n * -----Shadows\n * -----Grid\n * -----Data table\n * -----Dialog\n * -----Snackbar\n * -----Tooltip\n * -----Chip\n *\n * Even though all variables have the `!default` directive, most of them\n * should not be changed as they are dependent one another. This can cause\n * visual distortions (like alignment issues) that are hard to track down\n * and fix.\n */\n\n\n/* ========== TYPOGRAPHY ========== */\n\n/* We're splitting fonts into \"preferred\" and \"performance\" in order to optimize\n page loading. For important text, such as the body, we want it to load\n immediately and not wait for the web font load, whereas for other sections,\n such as headers and titles, we're OK with things taking a bit longer to load.\n We do have some optional classes and parameters in the mixins, in case you\n definitely want to make sure you're using the preferred font and don't mind\n the performance hit.\n We should be able to improve on this once CSS Font Loading L3 becomes more\n widely available.\n*/\n$preferred_font: 'Roboto', 'Helvetica', 'Arial', sans-serif !default;\n$performance_font: 'Helvetica', 'Arial', sans-serif !default;\n\n/* ========== COLORS ========== */\n\n/**\n*\n* Material design color palettes.\n* @see http://www.google.com/design/spec/style/color.html\n*\n**/\n\n@import \"color-definitions\";\n@import \"functions\";\n\n/* ========== IMAGES ========== */\n$image_path: '/images' !default;\n\n/* ========== Color & Themes ========== */\n\n// Define whether individual color palette items should have classes created.\n// Setting this to true will remove individual color classes for each color in the palettes.\n// To improve overall performance (assuming they aren't used) by:\n// * Saving server bandwidth sending the extra classes\n// * Save client computation against the classes\n// it is RECOMMENDED you set this to true.\n$trim-color-classes: false !default;\n\n// Use color primarily for emphasis. Choose colors that fit with\n// your brand and provide good contrast between visual components.\n$color-primary: $palette-indigo-500 !default;\n$color-primary-dark: $palette-indigo-700 !default;\n$color-accent: $palette-pink-A200 !default;\n\n// Our primary is dark, so use $color-dark-contrast for overlaid text.\n$color-primary-contrast: $color-dark-contrast !default;\n// Our accent is dark, so use $color-dark-contrast for overlaid text.\n$color-accent-contrast: $color-dark-contrast !default;\n\n// Replace all colors with placeholders if we're generating a template.\n@if $styleguide-generate-template == true {\n $color-primary: '$color-primary';\n $color-primary-dark: '$color-primary-dark';\n $color-accent: '$color-accent';\n $color-primary-contrast: '$color-primary-contrast';\n $color-accent-contrast: '$color-accent-contrast';\n}\n\n/* ========== Typography ========== */\n\n// We use the following default color styles: text-color-primary and\n// text-color-secondary. For light themes, use text-color-primary-inverse\n// and text-color-secondary-inverse.\n\n$text-color-primary: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$text-link-color: unquote(\"rgb(#{$color-accent})\") !default;\n\n// Define whether to target elements directly for typographic enhancements.\n// Turning this off means you need to use mdl-* classes more often.\n// Other components may also fail to adhere to MD without these rules.\n// It is strongly recommended you leave this as true.\n\n$target-elements-directly: true !default;\n\n/* ========== Components ========== */\n\n/* ========== Standard Buttons ========== */\n\n// Default button colors.\n$button-primary-color: unquote(\"rgba(#{$palette-grey-500}, 0.20)\") !default;\n$button-secondary-color: unquote(\"rgb(#{$color-black})\") !default;\n$button-hover-color: $button-primary-color !default;\n$button-active-color: unquote(\"rgba(#{$palette-grey-500}, 0.40)\") !default;\n$button-focus-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n// Colored button colors.\n$button-primary-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-secondary-color-alt: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n$button-hover-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-active-color-alt: unquote(\"rgb(#{$color-primary})\") !default;\n$button-focus-color-alt: $button-focus-color !default;\n\n// Ripple color for colored raised buttons.\n$button-ripple-color-alt: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n\n// Disabled button colors.\n$button-primary-color-disabled: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n$button-secondary-color-disabled: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n// FAB colors and sizes.\n$button-fab-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-hover-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-active-color-alt: unquote(\"rgb(#{$color-accent})\") !default;\n$button-fab-text-color-alt: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n$button-fab-ripple-color-alt: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n\n// Icon button colors and sizes.\n$button-icon-color: unquote(\"rgb(#{$palette-grey-700})\") !default;\n$button-icon-focus-color: $button-focus-color !default;\n\n/* ========== Icon Toggles ========== */\n\n$icon-toggle-color: unquote(\"rgb(#{$palette-grey-700})\") !default;\n$icon-toggle-focus-color: $button-focus-color !default;\n$icon-toggle-checked-color: unquote(\"rgb(#{$color-primary})\") !default;\n$icon-toggle-checked-focus-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$icon-toggle-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n/* ========== Radio Buttons ========== */\n\n$radio-color: unquote(\"rgb(#{$color-primary})\") !default;\n$radio-off-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$radio-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n\n/* ========== Ripple effect ========== */\n\n$ripple-bg-color: unquote(\"rgb(#{$color-light-contrast})\") !default;\n\n/* ========== Layout ========== */\n\n$layout-nav-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n\n// Drawer\n$layout-drawer-bg-color: unquote(\"rgb(#{$palette-grey-50})\") !default;\n$layout-drawer-border-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$layout-text-color: unquote(\"rgb(#{$palette-grey-800})\") !default;\n$layout-drawer-navigation-color: #757575 !default;\n$layout-drawer-navigation-link-active-background: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$layout-drawer-navigation-link-active-color: unquote(\"rgb(#{$color-light-contrast})\") !default;\n\n// Header\n$layout-header-bg-color: unquote(\"rgb(#{$color-primary})\") !default;\n$layout-header-text-color: unquote(\"rgb(#{$color-primary-contrast})\") !default;\n$layout-header-nav-hover-color: unquote(\"rgba(#{$palette-grey-700}, 0.6)\") !default;\n$layout-header-tab-text-color: unquote(\"rgba(#{$color-primary-contrast}, 0.6)\") !default;\n\n// Tabs\n$layout-header-tab-highlight: unquote(\"rgb(#{$color-accent})\") !default;\n\n/* ========== Content Tabs ========== */\n\n$tab-highlight-color: unquote(\"rgb(#{$color-primary})\") !default;\n$tab-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$tab-active-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$tab-border-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n\n/* ========== Checkboxes ========== */\n\n$checkbox-color: unquote(\"rgb(#{$color-primary})\") !default;\n$checkbox-off-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$checkbox-disabled-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$checkbox-focus-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$checkbox-image-path: $image_path;\n\n/* ========== Switches ========== */\n\n$switch-color: unquote(\"rgb(#{$color-primary})\") !default;\n$switch-faded-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$switch-thumb-color: $switch-color !default;\n$switch-track-color: unquote(\"rgba(#{$color-primary}, 0.5)\") !default;\n\n$switch-off-thumb-color: unquote(\"rgb(#{$palette-grey-50})\") !default;\n$switch-off-track-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$switch-disabled-thumb-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n$switch-disabled-track-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n/* ========== Spinner ========== */\n\n$spinner-color-1: unquote(\"rgb(#{$palette-blue-400})\") !default;\n$spinner-color-2: unquote(\"rgb(#{$palette-red-500})\") !default;\n$spinner-color-3: unquote(\"rgb(#{$palette-yellow-600})\") !default;\n$spinner-color-4: unquote(\"rgb(#{$palette-green-500})\") !default;\n\n$spinner-single-color: unquote(\"rgb(#{$color-primary})\") !default;\n\n/* ========== Text fields ========== */\n\n$input-text-background-color: transparent !default;\n$input-text-label-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$input-text-bottom-border-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n$input-text-highlight-color: unquote(\"rgb(#{$color-primary})\") !default;\n$input-text-disabled-color: $input-text-bottom-border-color !default;\n$input-text-disabled-text-color: $input-text-label-color !default;\n$input-text-error-color: unquote(\"rgb(#{$palette-red-A700})\") !default;\n\n/* ========== Card ========== */\n\n$card-background-color: unquote(\"rgb(#{$color-white})\") !default;\n$card-text-color: unquote(\"rgb(#{$color-black})\") !default;\n$card-image-placeholder-color: unquote(\"rgb(#{$color-accent})\") !default;\n$card-supporting-text-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$card-border-color: rgba(0,0,0,0.1) !default;\n$card-subtitle-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n\n/* ========== Sliders ========== */\n\n$range-bg-color: unquote(\"rgba(#{$color-black}, 0.26)\") !default;\n$range-color: unquote(\"rgb(#{$color-primary})\") !default;\n$range-faded-color: unquote(\"rgba(#{$color-primary}, 0.26)\") !default;\n$range-bg-focus-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n/* ========== Progress ========== */\n$progress-main-color: unquote(\"rgb(#{$color-primary})\") !default;\n$progress-secondary-color: unquote(\"rgba(#{$color-primary-contrast}, 0.7)\") !default;\n$progress-fallback-buffer-color: unquote(\"rgba(#{$color-primary-contrast}, 0.9)\") !default;\n$progress-image-path: $image_path;\n\n/* ========== List ========== */\n\n$list-main-text-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$list-supporting-text-text-color: unquote(\"rgba(#{$color-black}, 0.54)\") !default;\n$list-icon-color: unquote(\"rgb(#{$palette-grey-600})\") !default;\n$list-avatar-color: white !default;\n\n/* ========== Item ========== */\n\n// Default Item Colors\n$default-item-text-color: unquote(\"rgba(#{$color-black}, 0.87)\") !default;\n$default-item-outline-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n$default-item-hover-bg-color: unquote(\"rgb(#{$palette-grey-200})\") !default;\n$default-item-focus-bg-color: unquote(\"rgb(#{$palette-grey-200})\") !default;\n$default-item-active-bg-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$default-item-divider-color: unquote(\"rgba(#{$color-black}, 0.12)\") !default;\n\n// Disabled Button Colors\n$disabled-item-text-color: unquote(\"rgb(#{$palette-grey-400})\") !default;\n\n/* ========== Dropdown menu ========== */\n\n$default-dropdown-bg-color: unquote(\"rgb(#{$color-white})\") !default;\n\n/* ========== Tooltips ========== */\n\n$tooltip-text-color: unquote(\"rgb(#{$color-white})\") !default;\n$tooltip-background-color: unquote(\"rgba(#{$palette-grey-700}, 0.9)\") !default;\n\n/* ========== Footer ========== */\n\n$footer-bg-color: unquote(\"rgb(#{$palette-grey-800})\") !default;\n$footer-color: unquote(\"rgb(#{$palette-grey-500})\") !default;\n$footer-heading-color: unquote(\"rgb(#{$palette-grey-300})\") !default;\n$footer-button-fill-color: $footer-color !default;\n$footer-underline-color: $footer-color !default;\n\n\n/* TEXTFIELD */\n\n$input-text-font-size: 16px !default;\n$input-text-width: 100% !default;\n$input-text-padding: 4px !default;\n$input-text-vertical-spacing: 20px !default;\n\n$input-text-button-size: 32px !default;\n$input-text-floating-label-fontsize: 12px !default;\n$input-text-expandable-icon-top: 16px !default;\n\n\n/* SWITCH */\n\n$switch-label-font-size: 16px !default;\n$switch-label-height: 24px !default;\n$switch-track-height: 14px !default;\n$switch-track-length: 36px !default;\n$switch-thumb-size: 20px !default;\n$switch-track-top: ($switch-label-height - $switch-track-height) / 2 !default;\n$switch-thumb-top: ($switch-label-height - $switch-thumb-size) / 2 !default;\n$switch-ripple-size: $switch-label-height * 2 !default;\n$switch-helper-size: 8px !default;\n\n/* SPINNER */\n\n$spinner-size: 28px !default;\n$spinner-stroke-width: 3px !default;\n\n// Amount of circle the arc takes up.\n$spinner-arc-size: 270deg !default;\n// Time it takes to expand and contract arc.\n$spinner-arc-time: 1333ms !default;\n// How much the start location of the arc should rotate each time.\n$spinner-arc-start-rot: 216deg !default;\n\n$spinner-duration: 360 * $spinner-arc-time / (\n strip-units($spinner-arc-start-rot + (360deg - $spinner-arc-size)));\n\n\n/* RADIO */\n\n$radio-label-font-size: 16px !default;\n$radio-label-height: 24px !default;\n$radio-button-size: 16px !default;\n$radio-inner-margin: $radio-button-size / 4;\n$radio-padding: 8px !default;\n$radio-top-offset: ($radio-label-height - $radio-button-size) / 2;\n$radio-ripple-size: 42px !default;\n\n\n/* MENU */\n\n$menu-expand-duration: 0.3s !default;\n$menu-fade-duration: 0.2s !default;\n\n/* LIST */\n\n$list-border: 8px !default;\n$list-min-height: 48px !default;\n$list-min-padding: 16px !default;\n$list-bottom-padding: 20px !default;\n$list-avatar-text-left-distance: 72px !default;\n$list-icon-text-left-distance: 72px !default;\n\n$list-avatar-size: 40px !default;\n$list-icon-size: 24px !default;\n\n$list-two-line-height: 72px !default;\n$list-three-line-height: 88px !default;\n\n/* LAYOUT */\n\n$layout-drawer-narrow: 240px !default;\n$layout-drawer-wide: 456px !default;\n$layout-drawer-width: $layout-drawer-narrow !default;\n\n$layout-header-icon-size: 32px !default;\n$layout-screen-size-threshold: 1024px !default;\n$layout-header-icon-margin: 24px !default;\n$layout-drawer-button-mobile-size: 32px !default;\n$layout-drawer-button-desktop-size: 48px !default;\n\n$layout-header-mobile-row-height: 56px !default;\n$layout-mobile-header-height: $layout-header-mobile-row-height;\n$layout-header-desktop-row-height: 64px !default;\n$layout-desktop-header-height: $layout-header-desktop-row-height;\n\n$layout-header-desktop-baseline: 80px !default;\n$layout-header-mobile-baseline: 72px !default;\n$layout-header-mobile-indent: 16px !default;\n$layout-header-desktop-indent: 40px !default;\n\n$layout-tab-font-size: 14px !default;\n$layout-tab-bar-height: 48px !default;\n$layout-tab-mobile-padding: 12px !default;\n$layout-tab-desktop-padding: 24px !default;\n$layout-tab-highlight-thickness: 2px !default;\n\n\n/* ICON TOGGLE */\n\n$icon-toggle-size: 32px !default;\n$icon-toggle-font-size: 24px !default;\n$icon-toggle-ripple-size: 36px !default;\n\n/* FOOTER */\n\n/*mega-footer*/\n$footer-min-padding: 16px !default;\n$footer-padding-sides: 40px !default;\n$footer-heading-font-size: 14px !default;\n$footer-heading-line-height: (1.7 * $footer-heading-font-size) !default;\n$footer-btn-size: 36px !default;\n\n/*mini-footer*/\n$padding: 16px !default;\n$footer-heading-font-size: 24px !default;\n$footer-heading-line-height: (1.5 * $footer-heading-font-size) !default;\n$footer-btn-size: 36px !default;\n\n/* CHECKBOX */\n\n$checkbox-label-font-size: 16px !default;\n$checkbox-label-height: 24px !default;\n$checkbox-button-size: 16px !default;\n$checkbox-inner-margin: 2px !default;\n$checkbox-padding: 8px !default;\n$checkbox-top-offset:\n($checkbox-label-height - $checkbox-button-size - $checkbox-inner-margin) / 2;\n$checkbox-ripple-size: $checkbox-label-height * 1.5;\n\n/* CARD */\n\n/* Card dimensions */\n$card-width: 330px !default;\n$card-height: 200px !default;\n$card-font-size: 16px !default;\n$card-title-font-size: 24px !default;\n$card-subtitle-font-size: 14px !default;\n$card-horizontal-padding: 16px !default;\n$card-vertical-padding: 16px !default;\n\n$card-title-perspective-origin-x: 165px !default;\n$card-title-perspective-origin-y: 56px !default;\n\n$card-title-transform-origin-x: 165px !default;\n$card-title-transform-origin-y: 56px !default;\n\n$card-title-text-transform-origin-x: 149px !default;\n$card-title-text-transform-origin-y: 48px !default;\n\n$card-supporting-text-font-size: 1rem !default;\n$card-supporting-text-line-height: 18px !default;\n\n$card-actions-font-size: 16px !default;\n\n$card-title-text-font-weight: 300 !default;\n$card-z-index: 1 !default;\n\n/* Cover image */\n$card-cover-image-height: 186px !default;\n$card-background-image-url: '' !default;\n\n\n/* BUTTON */\n/**\n *\n * Dimensions\n *\n */\n$button-min-width: 64px !default;\n$button-height: 36px !default;\n$button-padding: 16px !default;\n$button-margin: 4px !default;\n$button-border-radius: 2px !default;\n\n$button-fab-size: 56px !default;\n$button-fab-size-mini: 40px !default;\n$button-fab-font-size: 24px !default;\n\n$button-icon-size: 32px !default;\n$button-icon-size-mini: 24px !default;\n\n\n/* ANIMATION */\n$animation-curve-fast-out-slow-in: cubic-bezier(0.4, 0, 0.2, 1) !default;\n$animation-curve-linear-out-slow-in: cubic-bezier(0, 0, 0.2, 1) !default;\n$animation-curve-fast-out-linear-in: cubic-bezier(0.4, 0, 1, 1) !default;\n\n$animation-curve-default: $animation-curve-fast-out-slow-in !default;\n\n\n/* PROGRESS */\n$bar-height: 4px !default;\n\n/* BADGE */\n$badge-font-size: 12px !default;\n$badge-color: unquote(\"rgb(#{$color-accent-contrast})\") !default;\n$badge-color-inverse: unquote(\"rgb(#{$color-accent})\") !default;\n$badge-background: unquote(\"rgb(#{$color-accent})\") !default;\n$badge-background-inverse: unquote(\"rgba(#{$color-accent-contrast},0.2)\") !default;\n$badge-size : 22px !default;\n$badge-padding: 2px !default;\n$badge-overlap: 12px !default;\n\n/* SHADOWS */\n\n$shadow-key-umbra-opacity: 0.2 !default;\n$shadow-key-penumbra-opacity: 0.14 !default;\n$shadow-ambient-shadow-opacity: 0.12 !default;\n\n/* GRID */\n\n$grid-desktop-columns: 12 !default;\n$grid-desktop-gutter: 16px !default;\n$grid-desktop-margin: 16px !default;\n\n$grid-desktop-breakpoint: 840px !default;\n\n$grid-tablet-columns: 8 !default;\n$grid-tablet-gutter: $grid-desktop-gutter !default;\n$grid-tablet-margin: $grid-desktop-margin !default;\n\n$grid-tablet-breakpoint: 480px !default;\n\n$grid-phone-columns: 4 !default;\n$grid-phone-gutter: $grid-desktop-gutter !default;\n$grid-phone-margin: $grid-desktop-margin !default;\n\n$grid-cell-default-columns: $grid-phone-columns !default;\n$grid-max-columns: $grid-desktop-columns !default;\n\n/* DATA TABLE */\n\n$data-table-font-size: 13px !default;\n$data-table-header-font-size: 12px !default;\n$data-table-header-sort-icon-size: 16px !default;\n\n$data-table-header-color: rgba(#000, 0.54) !default;\n$data-table-header-sorted-color: rgba(#000, 0.87) !default;\n$data-table-header-sorted-icon-hover-color: rgba(#000, 0.26) !default;\n$data-table-divider-color: rgba(#000, 0.12) !default;\n\n$data-table-hover-color: #eeeeee !default;\n$data-table-selection-color: #e0e0e0 !default;\n\n$data-table-dividers: 1px solid $data-table-divider-color !default;\n\n$data-table-row-height: 48px !default;\n$data-table-last-row-height: 56px !default;\n$data-table-header-height: 56px !default;\n\n$data-table-column-spacing: 36px !default;\n$data-table-column-padding: $data-table-column-spacing / 2;\n\n$data-table-card-header-height: 64px !default;\n$data-table-card-title-top: 20px !default;\n$data-table-card-padding: 24px !default;\n$data-table-button-padding-right: 16px !default;\n$data-table-cell-top: $data-table-card-padding / 2;\n\n/* DIALOG */\n$dialog-content-color: $card-supporting-text-text-color;\n\n/* SNACKBAR */\n\n// Hard coded since the color is not present in any palette.\n$snackbar-background-color: #323232 !default;\n$snackbar-tablet-breakpoint: $grid-tablet-breakpoint;\n$snackbar-action-color: unquote(\"rgb(#{$color-accent})\") !default;\n\n/* TOOLTIP */\n$tooltip-font-size: 10px !default;\n$tooltip-font-size-large: 14px !default;\n\n/* CHIP */\n$chip-bg-color: rgb(222, 222, 222) !default;\n$chip-bg-active-color: rgb(214, 214, 214) !default;\n$chip-height: 32px !default;\n$chip-font-size: 13px !default; \n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n\n.mdl-mini-footer {\n display: flex;\n flex-flow: row wrap;\n justify-content: space-between;\n\n padding: ($padding * 2) $padding;\n\n color: $footer-color;\n background-color: $footer-bg-color;\n\n &:after {\n content: '';\n display: block;\n }\n\n & .mdl-logo {\n line-height: $footer-btn-size;\n }\n}\n\n.mdl-mini-footer--link-list,\n.mdl-mini-footer__link-list {\n display: flex;\n flex-flow: row nowrap;\n\n list-style: none;\n\n margin: 0;\n padding: 0;\n\n & li {\n margin-bottom: 0;\n margin-right: $padding;\n\n @media screen and (min-width: 760px) {\n line-height: $footer-btn-size;\n }\n }\n\n & a {\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n }\n}\n\n.mdl-mini-footer--left-section,\n.mdl-mini-footer__left-section {\n display: inline-block;\n order: 0;\n}\n\n.mdl-mini-footer--right-section,\n.mdl-mini-footer__right-section {\n display: inline-block;\n order: 1;\n}\n\n.mdl-mini-footer--social-btn,\n.mdl-mini-footer__social-btn {\n width: $footer-btn-size;\n height: $footer-btn-size;\n\n padding: 0;\n margin: 0;\n\n background-color: $footer-button-fill-color;\n\n border: none;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n\n.mdl-card {\n display: flex;\n flex-direction: column;\n font-size: $card-font-size;\n font-weight: 400;\n min-height: $card-height;\n overflow: hidden;\n width: $card-width;\n z-index: $card-z-index;\n position: relative;\n background: $card-background-color;\n border-radius: 2px;\n box-sizing: border-box;\n}\n\n.mdl-card__media {\n background-color: $card-image-placeholder-color;\n background-repeat: repeat;\n background-position: 50% 50%;\n background-size: cover;\n background-origin: padding-box;\n background-attachment: scroll;\n box-sizing: border-box;\n}\n\n.mdl-card__title {\n align-items: center;\n color: $card-text-color;\n display: block;\n display: flex;\n justify-content: stretch;\n line-height: normal;\n padding: $card-vertical-padding $card-horizontal-padding;\n perspective-origin: $card-title-perspective-origin-x $card-title-perspective-origin-y;\n transform-origin: $card-title-transform-origin-x $card-title-transform-origin-y;\n box-sizing: border-box;\n\n &.mdl-card--border {\n border-bottom: 1px solid $card-border-color;\n }\n}\n\n.mdl-card__title-text {\n align-self: flex-end;\n color: inherit;\n display: block;\n display: flex;\n font-size: $card-title-font-size;\n font-weight: $card-title-text-font-weight;\n line-height: normal;\n overflow: hidden;\n transform-origin: $card-title-text-transform-origin-x $card-title-text-transform-origin-y;\n margin: 0;\n}\n\n.mdl-card__subtitle-text {\n font-size: $card-subtitle-font-size;\n color: $card-subtitle-color;\n margin: 0;\n}\n\n.mdl-card__supporting-text {\n color: $card-supporting-text-text-color;\n font-size: $card-supporting-text-font-size;\n line-height: $card-supporting-text-line-height;\n overflow: hidden;\n padding: $card-vertical-padding $card-horizontal-padding;\n width: 90%;\n\n &.mdl-card--border {\n border-bottom: 1px solid $card-border-color;\n }\n}\n\n.mdl-card__actions {\n font-size: $card-actions-font-size;\n line-height: normal;\n width: 100%;\n background-color: rgba(0,0,0,0);\n padding: 8px;\n box-sizing: border-box;\n\n &.mdl-card--border {\n border-top: 1px solid $card-border-color;\n }\n}\n\n.mdl-card--expand {\n flex-grow: 1;\n}\n\n\n.mdl-card__menu {\n position: absolute;\n right: 16px;\n top: 16px;\n}\n","/**\n * Copyright 2015 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@import \"../variables\";\n@import \"../mixins\";\n\n// The button component. Defaults to a flat button.\n.mdl-button {\n background: transparent;\n border: none;\n border-radius: $button-border-radius;\n color: $button-secondary-color;\n position: relative;\n height: $button-height;\n margin: 0;\n min-width: $button-min-width;\n padding: 0 $button-padding;\n display: inline-block;\n @include typo-button();\n overflow: hidden;\n will-change: box-shadow;\n transition: box-shadow 0.2s $animation-curve-fast-out-linear-in,\n background-color 0.2s $animation-curve-default,\n color 0.2s $animation-curve-default;\n outline: none;\n cursor: pointer;\n text-decoration: none;\n text-align: center;\n line-height: $button-height;\n vertical-align: middle;\n\n &::-moz-focus-inner {\n border: 0;\n }\n\n &:hover {\n background-color: $button-hover-color;\n }\n\n &:focus:not(:active) {\n background-color: $button-focus-color;\n }\n\n &:active {\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n color: $button-primary-color-alt;\n\n &:focus:not(:active) {\n background-color: $button-focus-color-alt;\n }\n }\n}\n\ninput.mdl-button[type=\"submit\"] {\n -webkit-appearance:none;\n}\n\n // Raised buttons\n .mdl-button--raised {\n background: $button-primary-color;\n @include shadow-2dp();\n\n &:active {\n @include shadow-4dp();\n background-color: $button-active-color;\n }\n\n &:focus:not(:active) {\n @include focus-shadow();\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n background: $button-primary-color-alt;\n color: $button-secondary-color-alt;\n\n &:hover {\n background-color: $button-hover-color-alt;\n }\n\n &:active {\n background-color: $button-active-color-alt;\n }\n\n &:focus:not(:active) {\n background-color: $button-active-color-alt;\n }\n\n & .mdl-ripple {\n background: $button-ripple-color-alt;\n }\n }\n }\n\n\n // FABs\n .mdl-button--fab {\n border-radius: 50%;\n font-size: $button-fab-font-size;\n height: $button-fab-size;\n margin: auto;\n min-width: $button-fab-size;\n width: $button-fab-size;\n padding: 0;\n overflow: hidden;\n background: $button-primary-color;\n box-shadow: 0 1px 1.5px 0 rgba(0,0,0,0.12), 0 1px 1px 0 rgba(0,0,0,0.24);\n position: relative;\n line-height: normal;\n\n & .material-icons {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);\n line-height: $button-fab-font-size;\n width: $button-fab-font-size;\n }\n\n &.mdl-button--mini-fab {\n height: $button-fab-size-mini;\n min-width: $button-fab-size-mini;\n width: $button-fab-size-mini;\n }\n\n & .mdl-button__ripple-container {\n border-radius: 50%;\n // Fixes clipping bug in Safari.\n -webkit-mask-image: -webkit-radial-gradient(circle, white, black);\n }\n\n &:active {\n @include shadow-4dp();\n background-color: $button-active-color;\n }\n\n &:focus:not(:active) {\n @include focus-shadow();\n background-color: $button-active-color;\n }\n\n &.mdl-button--colored {\n background: $button-fab-color-alt;\n color: $button-fab-text-color-alt;\n\n &:hover {\n background-color: $button-fab-hover-color-alt;\n }\n\n &:focus:not(:active) {\n background-color: $button-fab-active-color-alt;\n }\n\n &:active {\n background-color: $button-fab-active-color-alt;\n }\n\n & .mdl-ripple {\n background: $button-fab-ripple-color-alt;\n }\n }\n }\n\n\n // Icon buttons\n .mdl-button--icon {\n border-radius: 50%;\n font-size: $button-fab-font-size;\n height: $button-icon-size;\n margin-left: 0;\n margin-right: 0;\n min-width: $button-icon-size;\n width: $button-icon-size;\n padding: 0;\n overflow: hidden;\n color: inherit;\n line-height: normal;\n\n & .material-icons {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);\n line-height: $button-fab-font-size;\n width: $button-fab-font-size;\n }\n\n &.mdl-button--mini-icon {\n height: $button-icon-size-mini;\n min-width: $button-icon-size-mini;\n width: $button-icon-size-mini;\n\n & .material-icons {\n top: ($button-icon-size-mini - $button-fab-font-size) / 2;\n left: ($button-icon-size-mini - $button-fab-font-size) / 2;\n }\n }\n\n & .mdl-button__ripple-container {\n border-radius: 50%;\n // Fixes clipping bug in Safari.\n -webkit-mask-image: -webkit-radial-gradient(circle, white, black);\n }\n }\n\n\n // Ripples\n .mdl-button__ripple-container {\n display: block;\n height: 100%;\n left: 0px;\n position: absolute;\n top: 0px;\n width: 100%;\n z-index: 0;\n overflow: hidden;\n\n .mdl-button[disabled] & .mdl-ripple,\n .mdl-button.mdl-button--disabled & .mdl-ripple {\n background-color: transparent;\n }\n }\n\n// Colorized buttons\n\n.mdl-button--primary.mdl-button--primary {\n color: $button-primary-color-alt;\n & .mdl-ripple {\n background: $button-secondary-color-alt;\n }\n &.mdl-button--raised, &.mdl-button--fab {\n color: $button-secondary-color-alt;\n background-color: $button-primary-color-alt;\n }\n}\n\n.mdl-button--accent.mdl-button--accent {\n color: $button-fab-color-alt;\n & .mdl-ripple {\n background: $button-fab-text-color-alt;\n }\n &.mdl-button--raised, &.mdl-button--fab {\n color: $button-fab-text-color-alt;\n background-color: $button-fab-color-alt;\n }\n}\n\n// Disabled buttons\n\n.mdl-button {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n color: $button-secondary-color-disabled;\n cursor: default;\n background-color: transparent;\n }\n\n &--fab {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n background-color: $button-primary-color-disabled;\n color: $button-secondary-color-disabled;\n }\n }\n\n &--raised {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n background-color: $button-primary-color-disabled;\n color: $button-secondary-color-disabled;\n box-shadow: none;\n }\n }\n &--colored {\n // Bump up specificity by using [disabled] twice.\n &[disabled][disabled],\n &.mdl-button--disabled.mdl-button--disabled {\n color: $button-secondary-color-disabled;\n }\n }\n}\n\n// Align icons inside buttons with text\n.mdl-button .material-icons {\n vertical-align: middle;\n}\n","// SIMPLE GRID - SASS/SCSS\n\n\n// fonts\n$font-weight-light: 300;\n$font-weight-regular: 400;\n$font-weight-heavy: 700;\n\n// colors\n$dark-grey: #333447;\n$dark-gray: #333447; // for the Americans\n\n\n.font-light {\n font-weight: $font-weight-light;\n}\n\n.font-regular {\n font-weight: $font-weight-regular;\n}\n\n.font-heavy {\n font-weight: $font-weight-heavy;\n}\n\n// utility\n\n.left {\n text-align: left;\n}\n\n.right {\n text-align: right;\n}\n\n.center {\n text-align: center;\n margin-left: auto;\n margin-right: auto;\n}\n\n.justify {\n text-align: justify;\n}\n\n.hidden-sm {\n display: none;\n}\n\n// grid\n\n$width: 98%;\n$gutter: 2%;\n$breakpoint-small: 33.75em; // 540px\n$breakpoint-med: 45em; // 720px\n$breakpoint-large: 60em; // 960px\n\n.container {\n width: 100%;\n margin-left: auto;\n margin-right: auto;\n}\n\n.row {\n position: relative;\n width: 100%;\n}\n\n.row [class^=\"col\"] {\n float: left;\n margin: 0.5rem 1%;\n min-height: 0.125rem;\n}\n\n.row::after {\n content: \"\";\n display: table;\n clear: both;\n}\n\n.col-1,\n.col-2,\n.col-3,\n.col-4,\n.col-5,\n.col-6,\n.col-7,\n.col-8,\n.col-9,\n.col-10,\n.col-11,\n.col-12 {\n width: $width;\n}\n\n.col-1-sm {\n width: ($width / 12) - ($gutter * 11 / 12);\n}\n\n.col-2-sm {\n width: ($width / 6) - ($gutter * 10 / 12);\n}\n\n.col-3-sm {\n width: ($width / 4) - ($gutter * 9 / 12);\n}\n\n.col-4-sm {\n width: ($width / 3) - ($gutter * 8 / 12);\n}\n\n.col-5-sm {\n width: ($width / (12 / 5)) - ($gutter * 7 / 12);\n}\n\n.col-6-sm {\n width: ($width / 2) - ($gutter * 6 / 12);\n}\n\n.col-7-sm {\n width: ($width / (12 / 7)) - ($gutter * 5 / 12);\n}\n\n.col-8-sm {\n width: ($width / (12 / 8)) - ($gutter * 4 / 12);\n}\n\n.col-9-sm {\n width: ($width / (12 / 9)) - ($gutter * 3 / 12);\n}\n\n.col-10-sm {\n width: ($width / (12 / 10)) - ($gutter * 2 / 12);\n}\n\n.col-11-sm {\n width: ($width / (12 / 11)) - ($gutter * 1 / 12);\n}\n\n.col-12-sm {\n width: $width;\n}\n\n@media only screen and (min-width: $breakpoint-med) {\n .col-1 {\n width: ($width / 12) - ($gutter * 11 / 12);\n }\n .col-2 {\n width: ($width / 6) - ($gutter * 10 / 12);\n }\n .col-3 {\n width: ($width / 4) - ($gutter * 9 / 12);\n }\n .col-4 {\n width: ($width / 3) - ($gutter * 8 / 12);\n }\n .col-5 {\n width: ($width / (12 / 5)) - ($gutter * 7 / 12);\n }\n .col-6 {\n width: ($width / 2) - ($gutter * 6 / 12);\n }\n .col-7 {\n width: ($width / (12 / 7)) - ($gutter * 5 / 12);\n }\n .col-8 {\n width: ($width / (12 / 8)) - ($gutter * 4 / 12);\n }\n .col-9 {\n width: ($width / (12 / 9)) - ($gutter * 3 / 12);\n }\n .col-10 {\n width: ($width / (12 / 10)) - ($gutter * 2 / 12);\n }\n .col-11 {\n width: ($width / (12 / 11)) - ($gutter * 1 / 12);\n }\n .col-12 {\n width: $width;\n }\n\n .hidden-sm {\n display: block;\n }\n}\n\n.row {\n display: -webkit-box;\n display: -webkit-flex;\n display: -ms-flexbox;\n display: flex;\n flex-wrap: wrap;\n}\n\n.row > [class*='col-'] {\n display: flex;\n flex-direction: column;\n}\n","\n/*\nMaterial Icons\n*/\n\n.material-icons {\n font-family: 'Material Icons';\n font-weight: normal;\n font-style: normal;\n font-size: 24px; /* Preferred icon size */\n display: inline-block;\n line-height: 1;\n text-transform: none;\n letter-spacing: normal;\n word-wrap: normal;\n white-space: nowrap;\n direction: ltr;\n \n /* Support for all WebKit browsers. */\n -webkit-font-smoothing: antialiased;\n /* Support for Safari and Chrome. */\n text-rendering: optimizeLegibility;\n \n /* Support for Firefox. */\n -moz-osx-font-smoothing: grayscale;\n \n /* Support for IE. */\n font-feature-settings: 'liga';\n }","html {\n font-size: $font_size;\n}\n\nbody {\n display: block !important;\n background-color: $background_color;\n font-size: 1rem;\n line-height: 1.5rem;\n font-family: $body_font_family;\n}\n\n.mdl-layout__content:focus {\n outline: none;\n }\n\n.mdl-layout__content header.mdl-layout__drawer {\n display: none;\n}\n\n.mdl-layout--fixed-drawer>.mdl-layout__content {\n margin-left: 300px; \n}\n\n@media screen and (max-width: 1024px) {\n .mdl-layout--fixed-drawer>.mdl-layout__content {\n margin-left:0\n }\n}\n\nh1, h2, h3, h4, h5, h6, blockquote, span.mdl-layout-title,\na.download > code.download {\n font-family: $body_font_family;\n}\n\nh1, h2, h3, h4, h5, h6, .toc-backref, .contents, .toctree-wrapper, .contents a, .toctree-wrapper a, .globaltoc a.current {\n color: $color-mxnet !important;\n}\n\na {\n text-decoration: none;\n}\n\n.page-content {\n font-size: 1rem;\n p, ul, ol, dl, dd, dt, table, th, td {\n font-size: 1rem;\n }\n}\n\n.brand {\n color: inherit;\n text-decoration: none;\n}\n\n.section {\n overflow-x: auto;\n}\n\n\n/*\n * Figure Directive Styles\n */\n img {\n max-width: 100%;\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n\ndiv.figure {\n p.caption {\n text-align: center;\n margin-top: .75rem;\n\n span.caption-number {\n font-style: normal;\n }\n .caption-number::after {\n content: \"\\00a0\";\n }\n }\n}\n\n.svg-icon {\n width: 16px;\n height: 16px;\n display: inline-block;\n fill: $grey-color-light;\n padding-right: 5px;\n padding-top: 4px;\n vertical-align: text-top;\n}\n\n/*\n * Download Link Styles\n */\na.download > i.material-icons {\n position: relative;\n top: 5px;\n}\n\na.download {\n text-decoration: none;\n}\n\n%clearfix:after {\n content: \"\";\n display: table;\n clear: both;\n}\n\n.wrapper {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));\n max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));\n margin-right: auto;\n margin-left: auto;\n padding-right: calc(#{$spacing-unit}+15px);\n padding-left: $spacing-unit;\n @extend %clearfix;\n\n @media screen and (max-width: $on-laptop) {\n max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));\n max-width: calc(#{$content-width} - (#{$spacing-unit}));\n padding-right: $spacing-unit / 2;\n padding-left: $spacing-unit / 2;\n }\n}\n\n","/*\nVariables\n*/\n$font_size: 16px;\n\n$background_color: #fafafa;\n$code_background: rgba(0,0,0,.05);\n\n$code_font_family: \"Menlo\", \"DejaVu Sans Mono\", \"Liberation Mono\", \"Consolas\", \"Ubuntu Mono\", \"Courier New\", \"andale mono\", \"lucida console\", monospace !default;\n$body_font_family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\" !default;\n$base-font-size: 17px !default;\n\n$xl-breakpoint: 1795px;\n$lg-breakpoint: 1200px;\n$md-breakpoint: 992px;\n$sm-breakpoint: 768px;\n$xs-breakpoint: 576px;\n\n$color-primary: $palette-blue-500;\n$color-primary-dark: $palette-blue-700 !default;\n$color-accent: $palette-deep-orange-A200 !default;\n$color-primary-contrast: $color-white !default;\n$color-accent-contrast: $color-white !default;\n\n\n$base-line-height: 1.5 !default;\n$spacing-unit: 30px !default;\n\n$color-mxnet: rgb(4,140,204);\n$color-mxnet-dark: rgb(4,60,110);\n$grey-color: #828282 !default;\n$grey-color-light: lighten($grey-color, 45%) !default;\n$grey-color-dark: darken($grey-color, 25%) !default;\n\n$table-text-align: left !default;\n\n// Width of the content area\n$content-width: 1150px !default;\n\n$on-palm: 600px !default;\n$on-palm: 900px !default;\n$on-laptop: 1024px !default;","/**\n * Layout Styles\n */\n $layout: (\n document: (\n xl: (\n width: 100%,\n )\n ),\n drawer-container: (\n width: $layout-drawer-width,\n ),\n side-doc-outline: (\n width: 230px,\n ),\n page-content: (\n md: (\n width: 90%,\n padding: 0 5%\n ),\n lg: (\n width: calc( 90% - 230px ),\n padding: 0 5%\n )\n )\n);\n\n.mdl-layout {\n margin-top: 76px;\n}\n\n\n.document {\n width: 100%;\n margin: 0 auto;\n display: flex;\n\n @media (min-width: $xl-breakpoint) {\n width: map-get(map-get(map-get($layout, document), xl), width);\n }\n .page-content {\n width: 100%;\n margin: 0 auto;\n padding: 0 12px;\n\n @media (min-width: $md-breakpoint) {\n width: map-get(map-get(map-get($layout, page-content), md), width);\n padding: map-get(map-get(map-get($layout, page-content), md), padding);\n }\n\n @media (min-width: $lg-breakpoint) {\n width: map-get(map-get(map-get($layout, page-content), lg), width);\n padding: map-get(map-get(map-get($layout, page-content), lg), padding);\n }\n }\n\n .side-doc-outline {\n width: map-get(map-get($layout, side-doc-outline), width);\n\n @media (max-width: $lg-breakpoint - 1) {\n display: none;\n } \n &--content {\n position: fixed;\n overflow-x: auto;\n overflow-y: auto;\n width: inherit;\n right: 0px;\n &::-webkit-scrollbar {\n width: 6px;\n }\n \n &::-webkit-scrollbar-track {\n border-radius: 6px;\n }\n \n &::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, .3);\n border-radius: 6px;\n box-shadow:0 0 0 1px rgba(255, 255, 255, .3);\n }\n }\n }\n\n}","@keyframes float-in {\n 0% {\n transform: translateY(0.5rem);\n opacity: 0;\n }\n\t100% {\n\t\ttransform: translateY(0);\n\t\topacity: 1;\n\t}\n}\n\n@keyframes float-out {\n 0% {\n transform: translateY(0);\n opacity: 1;\n }\n\t100% {\n\t\ttransform: translateY(0.5rem);\n\t\topacity: 0;\n\t}\n}\n\n.page-content {\n .headerlink {\n display: inline-block;\n text-decoration: none;\n margin-left: 0.8rem;\n color: inherit;\n opacity: 0;\n &:hover {\n animation: float-in 0.2s $animation-curve-fast-out-slow-in 0s forwards;\n }\n }\n\n h1, h2, h3, h4, h5, h6 {\n .toc-backref {\n text-decoration: none;\n }\n &:hover {\n .headerlink {\n animation: float-in 0.2s $animation-curve-fast-out-slow-in 0s forwards;\n }\n }\n }\n\n h1 {\n font-size: 2rem;\n line-height: 2.25rem;\n }\n\n h2 {\n font-size: 1.75rem;\n line-height: 2rem;\n padding-top: 1.5rem;\n margin-top: 0;\n margin-bottom: 1rem;\n }\n\n h3 {\n font-size: 1.5rem;\n line-height: 1.75rem;\n padding-top: 1rem;\n margin-top: 0px;\n margin-bottom: .75rem;\n }\n\n h4 {\n font-size: 1.25rem;\n line-height: 1.5rem;\n padding-top: .75rem;\n margin-top: 0px;\n margin-bottom: .5rem;\n }\n\n div.page-content h5 {\n font-size: 1.1rem;\n line-height: 1.5rem;\n padding-top: 2rem;\n margin-top: 0px;\n margin-bottom: 1rem;\n }\n\n div.page-content h6 {\n font-size: 1rem;\n line-height: 1.5rem;\n padding-top: 2rem;\n margin-top: 0px;\n margin-bottom: 1rem;\n }\n\n\n}\n","\n/*\n * Admonition Styles\n */\n $admonitions: (\n hint: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"help_outline\"\n ),\n note: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"info_outline\"\n ),\n seealso: (\n font-color: rgb(0, 188, 212),\n background-color: rgba(0, 188, 212, 0.1),\n icon-content: \"search\"\n ),\n warning: (\n font-color: rgb(255, 193, 7),\n background-color: rgba(255, 193, 7, 0.1),\n icon-content: \"warning\"\n ),\n attention: (\n font-color: rgb(255, 193, 7),\n background-color: rgba(255, 193, 7, 0.1),\n icon-content: \"warning\"\n ),\n tip: (\n font-color: rgb(139, 195, 74),\n background-color: rgba(139, 195, 74, 0.1),\n icon-content: \"lightbulb_outline\"\n ),\n important: (\n font-color: rgb(139, 195, 74),\n background-color: rgba(139, 195, 74, 0.1),\n icon-content: \"check_circle\"\n ),\n error: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n ),\n caution: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n ),\n danger: (\n font-color: rgb(244, 67, 54),\n background-color: rgba(244, 67, 54, 0.1),\n icon-content: \"error_outline\"\n )\n);\n\n @mixin admonition-style($type) {\n border-left: solid 4px map-get(map-get($admonitions, $type), font-color);\n background-color: map-get(map-get($admonitions, $type), background-color);\n .admonition-title {\n font-size: 16px;\n font-weight: bold;\n color: map-get(map-get($admonitions, $type), font-color);\n\n margin-top: 4px;\n margin-bottom: 8px;\n &::before {\n @extend .material-icons;\n position: relative;\n margin-right: 5px;\n top: 3px;\n content: map-get(map-get($admonitions, $type), icon-content);\n font-size: 18px;\n }\n }\n}\n\n.admonition {\n @extend .mdl-shadow--2dp;\n\n padding: 12px 20px;\n margin-top: 10px;\n margin-bottom: 10px;\n p.last {\n margin: 16px;\n }\n .admonition-title {\n font-size: 16px;\n font-weight: bold;\n color: #555;\n text-transform: uppercase;\n margin-top: 7px;\n }\n\n @each $type in (note, seealso, hint, warning, attention, tip, important, error, caution, danger) {\n &.#{$type} {\n @include admonition-style($type);\n }\n }\n}\n",".page-content {\n .highlight {\n margin: 1px 0;\n pre {\n background: $code_background;\n color: rgba(0,0,0,.87);\n font-family: $code_font_family;\n padding: 0.75rem;\n overflow: auto;\n overflow-y: hidden;\n .o, .nd {\n color: rgba(0,0,0,.87);\n }\n }\n }\n\n div.highlight-console div.highlight {\n background: none;\n }\n\n // for jupyter notebook output cell\n .output {\n .highlight {\n pre {\n color: rgba(0,0,0,.87);\n background: $background_color;\n border-width: 1px;\n border-color: #999;\n border-style: solid;\n padding: 0.75rem;\n }\n }\n }\n\n .code, code:not(.download) {\n margin: 0 0;\n font-family: $code_font_family;\n border-radius: 2px;\n span.pre {\n font-family: $code_font_family;\n }\n }\n\n .viewcode-link {\n padding-left: 2em;\n font-size: 80%;\n }\n\n .rubric, .method > dt, .function > dt, .class > dt {\n display: table;\n margin: 10px 0;\n font-size: 100%;\n line-height: normal;\n background: #e7f2fa;\n color: #2B98F0;\n border-top: solid 3px #55ADF3;\n padding: 10px;\n position: relative;\n .descname, .descclassname {\n color: rgba(0,0,0,.87);\n background: #e7f2fa;\n padding: 3px;\n }\n em {\n padding: 0 2px;\n }\n }\n\n\n .rubric {\n margin: 30px 0 10px 0;\n }\n\n\n .field-body {\n padding-left: 40px;\n ul {\n padding: 0 0 0 16px;\n margin: 0;\n }\n }\n\n // .docutils > dt {\n // padding: 6px;\n // display: table;\n // margin-bottom: 6px;\n // border: none;\n // border-left: solid 3px #ccc;\n // background: #f0f0f0;\n // color: #555;\n // }\n\n .seealso .docutils > dt {\n float: left;\n clear: left;\n padding: 0 6px;\n }\n\n .seealso .docutils > dd {\n padding-left: 6em;\n }\n .nblast {\n padding-bottom: 1em;\n }\n\n pre {\n font-size: 90%;\n background: #eee;\n color: #455A64;\n padding: 16px 32px;\n width: auto;\n border-radius: 4px;\n word-wrap: break-word;\n\n &:hover {\n @extend .mdl-shadow--2dp;\n\n &:before {\n font-family: $body_font_family;\n padding: 0 0.5rem;\n content: attr(click-to-copy);\n color: rgba(0, 0, 0, 0.5);\n border-radius: 4px;\n position: relative;\n float: right;\n top: -0.5rem;\n right: -0.5rem;\n background: rgb(200, 200, 200);\n font-size: 0.8rem;\n cursor: pointer;\n }\n }\n }\n}\n","/*\n * Quotation Block Styles\n */\n .page-content {\n blockquote {\n font-size: 1rem;\n padding: 0 1rem;\n border-left: 3px solid $code_background;\n\n &:after {\n content: \"\" !important;\n margin-left: 0;\n }\n &:before {\n content: \"\" !important;\n }\n }\n }\n",".page-content {\n table:not(.footnote):not(.indextable):not(.hlist):not(.option-list):not(.field-list) {\n @extend .mdl-data-table;\n @extend .mdl-shadow--2dp;\n\n margin: 1.5rem 0;\n table-layout: fixed;\n max-width: 100%;\n min-width: 70%;\n\n th, td {\n @extend .mdl-data-table__cell--non-numeric;\n white-space: normal;\n overflow-wrap: break-word;\n }\n\n caption {\n font-size: $font_size;\n margin: 1rem 0 0.8rem 0;\n white-space: normal;\n .caption-number {\n font-style: normal;\n }\n .caption-number::after {\n content: \"\\00a0\";\n }\n }\n\n }\n}\n",".globaltoc {\n \n .caption, .toc {\n display: none;\n }\n\n ul {\n\n list-style-type: none;\n padding: 0;\n margin: 0;\n\n li {\n min-height: 18px;\n .link-wrapper {\n display: flex;\n justify-content: space-between;\n > a {\n padding: 4px 0;\n display: block;\n width: 100%;\n font-size: 1rem;\n text-decoration: none;\n color: $layout-drawer-navigation-color;\n &.current {\n font-weight: bold;\n }\n }\n }\n }\n }\n\n .nav-toggle {\n padding: 0;\n float: right;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 36px;\n > a {\n padding: 0;\n margin-left: 0;\n margin-right: 4px;\n cursor: pointer;\n > i {\n font-size: 18px;\n }\n }\n &.show {\n transform: rotateZ(180deg);\n > a {\n margin-right: 0;\n margin-left: 4px;\n }\n }\n }\n\n nav {\n > ul > li > span.link-wrapper {\n padding-left: 8px;\n }\n > ul > li > ul > li > span.link-wrapper {\n padding-left: 16px;\n }\n > ul > li > ul > li > ul > li > span.link-wrapper {\n padding-left: 24px;\n }\n > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 32px;\n }\n > ul > li > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 40px;\n }\n > ul > li > ul > li > ul > li > ul > li > ul > li > ul> li > span.link-wrapper {\n padding-left: 48px;\n }\n }\n}\n",".localtoc {\n font-size: 0.75rem;\n padding-top: 1rem;\n\n .caption {\n padding-left: 12px;\n &-text {\n font-size: 0.9rem;\n font-weight: 700;\n }\n }\n\n > ul > li > a {\n display: none;\n }\n\n ul {\n padding: 0;\n list-style-type: none;\n }\n\n li {\n padding-left: 6px;\n }\n\n a {\n display: block;\n text-decoration: none;\n color: inherit;\n margin-top: 8px;\n padding-left: 8px;\n line-height: 1.1rem;\n \n &.current {\n padding-left: 5px;\n border-left: 3px solid;\n font-weight: bold;\n }\n }\n}","/*\r\n * Toctree and Contents Directive Styles\r\n */\r\n .toctree-wrapper,\r\n .contents.topic {\r\n border-left: 5px solid;\r\n }\r\n\r\n .toctree-wrapper > p.caption,\r\n .contents.topic > p.topic-title {\r\n color: rgb(117, 117, 117);\r\n font-size: 1rem;\r\n padding-left: 14px;\r\n }\r\n\r\n .toctree-wrapper ul,\r\n .contents.topic ul{\r\n padding-left: 14px;\r\n list-style: none;\r\n line-height: 30px;\r\n }\r\n\r\n .toctree-wrapper a,\r\n .contents.topic a {\r\n font-size: 1.2rem;\r\n text-decoration: none;\r\n .pre {\r\n font-size: 1rem;\r\n }\r\n }\r\n\r\n .toctree-wrapper > ul > li > a,\r\n .contents.topic > ul > li > a {\r\n font-size: 1.3rem;\r\n .pre {\r\n font-size: 1.1rem;\r\n }\r\n }\r\n",".page-content {\n ul {\n li {\n margin: .3rem 0;\n p {\n margin: 0;\n }\n }\n }\n .option-list {\n .option {\n font-family: $code_font_family;\n }\n td {\n padding: 0.5rem;\n border: none;\n }\n }\n}\n","/*\r\n * Drawer Styles\r\n */\r\n.mdl-layout {\r\n &__drawer {\r\n background-color: #fff;\r\n\r\n &::-webkit-scrollbar {\r\n width: 6px;\r\n }\r\n\r\n &::-webkit-scrollbar-track {\r\n border-radius: 6px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background-color: rgba(0, 0, 0, .3);\r\n border-radius: 6px;\r\n box-shadow:0 0 0 1px rgba(255, 255, 255, .3);\r\n }\r\n\r\n > .mdl-layout-title {\r\n font-weight: bold;\r\n text-align: right;\r\n margin: 0;\r\n padding: 0;\r\n line-height: 32px;\r\n border-bottom: 1px solid rgba(0,0,0,.1);\r\n min-height: 64px;\r\n .title {\r\n color: inherit;\r\n display: block;\r\n height: 100%;\r\n width: 100%;\r\n text-decoration: none;\r\n > img.logo {\r\n width: 100%;\r\n margin: 0;\r\n padding: 0;\r\n }\r\n\r\n &-text {\r\n font-weight: bold;\r\n text-align: right;\r\n padding: 0 10px;\r\n margin: 16px 0 8px 0;\r\n line-height: 32px;\r\n font-family: $body_font_family;\r\n color: inherit;\r\n display: block;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","/*\r\n * Header Styles\r\n */\r\n\r\nnav.breadcrumb {\r\n > a.mdl-navigation__link {\r\n padding: 0 8px;\r\n font-size: 18px;\r\n }\r\n @media (max-width: $lg-breakpoint - 1) {\r\n width: calc( 100% - 64px );\r\n a.mdl-navigation__link.is-active {\r\n overflow-x: hidden;\r\n width: 100%;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n text-overflow: ellipsis;\r\n }\r\n a.mdl-navigation__link:not(.is-active),\r\n i.material-icons {\r\n display: none;\r\n }\r\n }\r\n}\r\n\r\ndiv.mdl-layout__header {\r\n margin-top: 77px;\r\n}\r\n\r\n.mdl-layout__drawer-button {\r\n top: 13px !important;\r\n}\r\n\r\ndiv.mdl-layout__header-row.header-links {\r\n background: rgba(255,255,255,0.2);\r\n width: 100%;\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n\r\n a.mdl-navigation__link {\r\n font-size: 1rem;\r\n i {\r\n font-size: 1.2rem;\r\n margin: 0 8px;\r\n position: relative;\r\n bottom: -0.1rem;\r\n }\r\n };\r\n\r\n a.mdl-navigation__link:hover {\r\n background-color: unquote(\"rgb(#{$color-primary})\");\r\n color: #eeeeee;\r\n };\r\n a.mdl-navigation__link[href=\"#\"] {\r\n background-color: unquote(\"rgb(#{$color-primary})\");\r\n opacity: 1;\r\n color: #ffffff;\r\n };\r\n}\r\n\r\n/* mxnet-header */\r\n\r\n\r\n.site-title {\r\n font-weight: 300 !important;\r\n line-height: 57px;\r\n letter-spacing: -1px;\r\n margin-bottom: 0;\r\n float: left;\r\n color: white;\r\n\r\n &,\r\n &:visited {\r\n color: $grey-color-dark;\r\n }\r\n}\r\n\r\n\r\n.site-header {\r\n position: fixed;\r\n top: 0;\r\n width: 100%;\r\n min-height: 55px;\r\n padding-top: 10px;\r\n padding-bottom: 10px;\r\n background-color: $color-mxnet;\r\n z-index: 10;\r\n font-weight: 300;\r\n font-size: 17px;\r\n border-bottom: 1px solid white;\r\n}\r\n\r\n.site-header-logo {\r\n width: 120px;\r\n display: initial;\r\n}\r\n\r\n.site-nav {\r\n float: right;\r\n line-height: 57px;\r\n\r\n .nav-trigger {\r\n display: none;\r\n }\r\n\r\n .menu-icon {\r\n display: none;\r\n }\r\n\r\n .page-link {\r\n color: white;\r\n line-height: 1.5;\r\n font-weight: 300;\r\n // Gaps between nav items, but not on the last one\r\n &:not(:last-child) {\r\n margin-right: 40px;\r\n }\r\n\r\n &:hover {\r\n color: white;\r\n text-shadow: -0.06ex 0 white, 0.06ex 0 white;\r\n }\r\n }\r\n\r\n .page-link.page-current {\r\n color: white;\r\n text-decoration: underline;\r\n }\r\n\r\n @media screen and (max-width: $on-laptop) {\r\n position: absolute;\r\n top: 9px;\r\n right: 15px;\r\n background-color: rgb(23,141,201);\r\n border-radius: 2px;\r\n text-align: right;\r\n\r\n label[for=\"nav-trigger\"] {\r\n display: block;\r\n float: right;\r\n width: 36px;\r\n height: 36px;\r\n z-index: 2;\r\n cursor: pointer;\r\n }\r\n\r\n .menu-icon {\r\n display: block;\r\n float: right;\r\n width: 36px;\r\n height: 26px;\r\n line-height: 0;\r\n padding-top: 20px;\r\n text-align: center;\r\n\r\n > svg {\r\n fill: white;\r\n }\r\n }\r\n\r\n input ~ .trigger {\r\n clear: both;\r\n display: none;\r\n }\r\n\r\n input:checked ~ .trigger {\r\n display: block;\r\n padding-bottom: 5px;\r\n }\r\n\r\n .page-link {\r\n padding: 5px 10px;\r\n display: block;\r\n\r\n &:not(:last-child) {\r\n margin-right: 0;\r\n }\r\n\r\n margin-left: 20px;\r\n }\r\n }\r\n}","/*\r\n * Footer Styles\r\n */\r\nfooter.mdl-mini-footer {\r\n background-color: #212121;\r\n > div.mdl-mini-footer__left-section {\r\n margin-bottom: 20px;\r\n display: flex;\r\n flex-direction: column;\r\n .mdl-logo {\r\n font-size: 1.1rem;\r\n }\r\n ul {\r\n @extend .mdl-mini-footer__link-list;\r\n }\r\n }\r\n > div.mdl-mini-footer__right-section {\r\n font-size: 0.9rem;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: flex-end;\r\n\r\n a {\r\n color: inherit;\r\n font-weight: bold;\r\n text-decoration: none;\r\n }\r\n }\r\n p.caption {\r\n display: none;\r\n }\r\n}\r\n\r\n/*\r\n * Pagenation Block Styles\r\n */\r\n .pagenation {\r\n width: 100%;\r\n margin-top: 80px;\r\n height: 92px;\r\n background-color: #424242;\r\n display: flex;\r\n\r\n .button-common {\r\n text-transform: none;\r\n padding: 0;\r\n height: 92px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n color: #ffffff;\r\n }\r\n #button-prev {\r\n @extend .button-common;\r\n margin-right: auto;\r\n .pagenation-text {\r\n text-align: left;\r\n }\r\n \r\n }\r\n #button-next {\r\n @extend .button-common;\r\n margin-left: auto;\r\n flex-direction: row-reverse;\r\n .pagenation-text {\r\n text-align: right;\r\n }\r\n }\r\n\r\n &-arrow {\r\n &-L {\r\n margin-right: 20px;\r\n }\r\n &-R {\r\n margin-left: 20px;\r\n }\r\n }\r\n\r\n &-text {\r\n line-height: 30px;\r\n font-size: 20px;\r\n }\r\n\r\n &-direction {\r\n opacity: 0.7;\r\n font-size: 18px;\r\n }\r\n @media screen and (max-width: 1024px) {\r\n #button-prev {\r\n width: 20%;\r\n }\r\n \r\n #button-next {\r\n width: 80%;\r\n }\r\n \r\n #button-prev .pagenation-text {\r\n display: none;\r\n }\r\n }\r\n @media screen and (min-width: 1025px) {\r\n #button-prev,\r\n #button-next {\r\n width: 50%;\r\n }\r\n \r\n #button-prev .pagenation-text {\r\n display: block;\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Site footer\r\n */\r\n.site-footer {\r\n border-top: 1px solid $grey-color-light;\r\n padding: $spacing-unit 0;\r\n background-color: #424242;\r\n position: relative;\r\n z-index: 10;\r\n .footer-category-title {\r\n color: $color-mxnet;\r\n }\r\n a {\r\n color: $grey-color-light !important;\r\n\r\n &:visited {\r\n color: $grey-color-light !important;\r\n }\r\n }\r\n\r\n}\r\n\r\n.site-footer2 {\r\n background-color: #424242;\r\n padding-top: 40px;\r\n padding-bottom: 10px;\r\n position: relative;\r\n z-index: 10;\r\n}\r\n\r\n.footer-heading {\r\n margin-bottom: $spacing-unit / 2;\r\n}\r\n\r\n.contact-list,\r\n.social-media-list {\r\n list-style: none;\r\n margin-left: 0;\r\n}\r\n\r\n\r\n.footer-bottom-warning {\r\n font-size: 80%;\r\n color: white;\r\n float: left;\r\n}\r\n\r\n.footer-logo {\r\n width: 200px;\r\n margin-bottom: 30px;\r\n margin-top: 30px;\r\n}\r\n\r\n.footer-col {\r\n float: left;\r\n margin-bottom: $spacing-unit / 2;\r\n padding-left: $spacing-unit / 2;\r\n}\r\n\r\n.footer-text {\r\n color: $grey-color-light;\r\n}\r\n\r\n"," /*\r\n * Search Styles\r\n */\r\n#waterfall-exp::-webkit-input-placeholder {\r\n color: #ccc;\r\n}\r\n#waterfall-exp:-ms-input-placeholder {\r\n color: #ccc;\r\n}\r\n#waterfall-exp::-moz-placeholder {\r\n color: #ccc;\r\n}\r\n\r\nul.search span.highlighted {\r\n font-weight: bold;\r\n}\r\n\r\nul.search > li {\r\n margin-bottom: 24px;\r\n}\r\n\r\n#search-results {\r\n ul {\r\n list-style: none;\r\n padding: 0;\r\n li {\r\n > a {\r\n text-decoration: none;\r\n font-size: 1.2rem;\r\n }\r\n }\r\n }\r\n}\r\n","a.download {\n &:before {\n @extend .material-icons;\n content: \"file_download\";\n position: relative;\n top: 5px;\n margin-right: 5px;\n }\n}\n\nbutton.download {\n position: sticky;\n margin-left: 1em;\n}\n",".mdl-card {\n margin: 1em 1.5em 1em 0;\n display: inline-block;\n width: 250px;\n min-height: 140px;\n padding: 18px;\n}\n.mdl-card:hover {\n box-shadow: 0 10px 20px rgba(0,0,0,0.25), 0 6px 6px rgba(0,0,0,0.22);\n color: #000;\n cursor: pointer;\n}\n.mdl-card__title {\n padding: 0 0 1em 0;\n font-size: 18px;\n color: #444;\n}\n\n.mdl-card__supporting-text {\n line-height: 1.5rem;\n padding: 0px;\n width: 100%;\n}\n\n.head-card.mdl-card {\n width: auto;\n display: block;\n max-width: 800px;\n padding: 24px;\n}\n\n.head-card > .mdl-card__title {\n padding-bottom: 0px;\n height: 60px;\n font-weight: 700;\n text-transform: uppercase;\n}\n.head-card > .mdl-card__menu {\n color: #fff;\n}\n.head-card > .mdl-card__actions {\n padding: 0;\n}\n.cards {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n}\n"]} \ No newline at end of file diff --git a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.js b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.js index 6b3ab86993a7..7ca6cd602aa3 100644 --- a/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.js +++ b/docs/python_docs/themes/mx-theme/mxtheme/static/sphinx_materialdesign_theme.js @@ -1,31 +1,33 @@ parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c0&&e(s.children))},upgradeAllRegistered:function(){for(var e=0;e0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)&&(e.keyCode===this.Keycodes_.UP_ARROW?(e.preventDefault(),t[t.length-1].focus()):e.keyCode===this.Keycodes_.DOWN_ARROW&&(e.preventDefault(),t[0].focus()))}},h.prototype.handleItemKeyboardEvent_=function(e){if(this.element_&&this.container_){var t=this.element_.querySelectorAll("."+this.CssClasses_.ITEM+":not([disabled])");if(t&&t.length>0&&this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)){var s=Array.prototype.slice.call(t).indexOf(e.target);if(e.keyCode===this.Keycodes_.UP_ARROW)e.preventDefault(),s>0?t[s-1].focus():t[t.length-1].focus();else if(e.keyCode===this.Keycodes_.DOWN_ARROW)e.preventDefault(),t.length>s+1?t[s+1].focus():t[0].focus();else if(e.keyCode===this.Keycodes_.SPACE||e.keyCode===this.Keycodes_.ENTER){e.preventDefault();var i=new MouseEvent("mousedown");e.target.dispatchEvent(i),i=new MouseEvent("mouseup"),e.target.dispatchEvent(i),e.target.click()}else e.keyCode===this.Keycodes_.ESCAPE&&(e.preventDefault(),this.hide())}}},h.prototype.handleItemClick_=function(e){e.target.hasAttribute("disabled")?e.stopPropagation():(this.closing_=!0,window.setTimeout(function(e){this.hide(),this.closing_=!1}.bind(this),this.Constant_.CLOSE_TIMEOUT))},h.prototype.applyClip_=function(e,t){this.element_.classList.contains(this.CssClasses_.UNALIGNED)?this.element_.style.clip="":this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)?this.element_.style.clip="rect(0 "+t+"px 0 "+t+"px)":this.element_.classList.contains(this.CssClasses_.TOP_LEFT)?this.element_.style.clip="rect("+e+"px 0 "+e+"px 0)":this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)?this.element_.style.clip="rect("+e+"px "+t+"px "+e+"px "+t+"px)":this.element_.style.clip=""},h.prototype.removeAnimationEndListener_=function(e){e.target.classList.remove(h.prototype.CssClasses_.IS_ANIMATING)},h.prototype.addAnimationEndListener_=function(){this.element_.addEventListener("transitionend",this.removeAnimationEndListener_),this.element_.addEventListener("webkitTransitionEnd",this.removeAnimationEndListener_)},h.prototype.show=function(e){if(this.element_&&this.container_&&this.outline_){var t=this.element_.getBoundingClientRect().height,s=this.element_.getBoundingClientRect().width;this.container_.style.width=s+"px",this.container_.style.height=t+"px",this.outline_.style.width=s+"px",this.outline_.style.height=t+"px";for(var i=this.Constant_.TRANSITION_DURATION_SECONDS*this.Constant_.TRANSITION_DURATION_FRACTION,n=this.element_.querySelectorAll("."+this.CssClasses_.ITEM),a=0;a0&&this.showSnackbar(this.queuedNotifications_.shift())},u.prototype.cleanup_=function(){this.element_.classList.remove(this.cssClasses_.ACTIVE),setTimeout(function(){this.element_.setAttribute("aria-hidden","true"),this.textElement_.textContent="",Boolean(this.actionElement_.getAttribute("aria-hidden"))||(this.setActionHidden_(!0),this.actionElement_.textContent="",this.actionElement_.removeEventListener("click",this.actionHandler_)),this.actionHandler_=void 0,this.message_=void 0,this.actionText_=void 0,this.active=!1,this.checkQueue_()}.bind(this),this.Constant_.ANIMATION_LENGTH)},u.prototype.setActionHidden_=function(e){e?this.actionElement_.setAttribute("aria-hidden","true"):this.actionElement_.removeAttribute("aria-hidden")},i.register({constructor:u,classAsString:"MaterialSnackbar",cssClass:"mdl-js-snackbar",widget:!0});var E=function(e){this.element_=e,this.init()};window.MaterialSpinner=E,E.prototype.Constant_={MDL_SPINNER_LAYER_COUNT:4},E.prototype.CssClasses_={MDL_SPINNER_LAYER:"mdl-spinner__layer",MDL_SPINNER_CIRCLE_CLIPPER:"mdl-spinner__circle-clipper",MDL_SPINNER_CIRCLE:"mdl-spinner__circle",MDL_SPINNER_GAP_PATCH:"mdl-spinner__gap-patch",MDL_SPINNER_LEFT:"mdl-spinner__left",MDL_SPINNER_RIGHT:"mdl-spinner__right"},E.prototype.createLayer=function(e){var t=document.createElement("div");t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER),t.classList.add(this.CssClasses_.MDL_SPINNER_LAYER+"-"+e);var s=document.createElement("div");s.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),s.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);var i=document.createElement("div");i.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);var n=document.createElement("div");n.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER),n.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);for(var a=[s,i,n],l=0;l=this.maxRows&&e.preventDefault()},I.prototype.onFocus_=function(e){this.element_.classList.add(this.CssClasses_.IS_FOCUSED)},I.prototype.onBlur_=function(e){this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},I.prototype.onReset_=function(e){this.updateClasses_()},I.prototype.updateClasses_=function(){this.checkDisabled(),this.checkValidity(),this.checkDirty(),this.checkFocus()},I.prototype.checkDisabled=function(){this.input_.disabled?this.element_.classList.add(this.CssClasses_.IS_DISABLED):this.element_.classList.remove(this.CssClasses_.IS_DISABLED)},I.prototype.checkDisabled=I.prototype.checkDisabled,I.prototype.checkFocus=function(){Boolean(this.element_.querySelector(":focus"))?this.element_.classList.add(this.CssClasses_.IS_FOCUSED):this.element_.classList.remove(this.CssClasses_.IS_FOCUSED)},I.prototype.checkFocus=I.prototype.checkFocus,I.prototype.checkValidity=function(){this.input_.validity&&(this.input_.validity.valid?this.element_.classList.remove(this.CssClasses_.IS_INVALID):this.element_.classList.add(this.CssClasses_.IS_INVALID))},I.prototype.checkValidity=I.prototype.checkValidity,I.prototype.checkDirty=function(){this.input_.value&&this.input_.value.length>0?this.element_.classList.add(this.CssClasses_.IS_DIRTY):this.element_.classList.remove(this.CssClasses_.IS_DIRTY)},I.prototype.checkDirty=I.prototype.checkDirty,I.prototype.disable=function(){this.input_.disabled=!0,this.updateClasses_()},I.prototype.disable=I.prototype.disable,I.prototype.enable=function(){this.input_.disabled=!1,this.updateClasses_()},I.prototype.enable=I.prototype.enable,I.prototype.change=function(e){this.input_.value=e||"",this.updateClasses_()},I.prototype.change=I.prototype.change,I.prototype.init=function(){if(this.element_&&(this.label_=this.element_.querySelector("."+this.CssClasses_.LABEL),this.input_=this.element_.querySelector("."+this.CssClasses_.INPUT),this.input_)){this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)&&(this.maxRows=parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE),10),isNaN(this.maxRows)&&(this.maxRows=this.Constant_.NO_MAX_ROWS)),this.input_.hasAttribute("placeholder")&&this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER),this.boundUpdateClassesHandler=this.updateClasses_.bind(this),this.boundFocusHandler=this.onFocus_.bind(this),this.boundBlurHandler=this.onBlur_.bind(this),this.boundResetHandler=this.onReset_.bind(this),this.input_.addEventListener("input",this.boundUpdateClassesHandler),this.input_.addEventListener("focus",this.boundFocusHandler),this.input_.addEventListener("blur",this.boundBlurHandler),this.input_.addEventListener("reset",this.boundResetHandler),this.maxRows!==this.Constant_.NO_MAX_ROWS&&(this.boundKeyDownHandler=this.onKeyDown_.bind(this),this.input_.addEventListener("keydown",this.boundKeyDownHandler));var e=this.element_.classList.contains(this.CssClasses_.IS_INVALID);this.updateClasses_(),this.element_.classList.add(this.CssClasses_.IS_UPGRADED),e&&this.element_.classList.add(this.CssClasses_.IS_INVALID),this.input_.hasAttribute("autofocus")&&(this.element_.focus(),this.checkFocus())}},i.register({constructor:I,classAsString:"MaterialTextfield",cssClass:"mdl-js-textfield",widget:!0});var f=function(e){this.element_=e,this.init()};window.MaterialTooltip=f,f.prototype.Constant_={},f.prototype.CssClasses_={IS_ACTIVE:"is-active",BOTTOM:"mdl-tooltip--bottom",LEFT:"mdl-tooltip--left",RIGHT:"mdl-tooltip--right",TOP:"mdl-tooltip--top"},f.prototype.handleMouseEnter_=function(e){var t=e.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,n=this.element_.offsetWidth/2*-1,a=this.element_.offsetHeight/2*-1;this.element_.classList.contains(this.CssClasses_.LEFT)||this.element_.classList.contains(this.CssClasses_.RIGHT)?(s=t.width/2,i+a<0?(this.element_.style.top="0",this.element_.style.marginTop="0"):(this.element_.style.top=i+"px",this.element_.style.marginTop=a+"px")):s+n<0?(this.element_.style.left="0",this.element_.style.marginLeft="0"):(this.element_.style.left=s+"px",this.element_.style.marginLeft=n+"px"),this.element_.classList.contains(this.CssClasses_.TOP)?this.element_.style.top=t.top-this.element_.offsetHeight-10+"px":this.element_.classList.contains(this.CssClasses_.RIGHT)?this.element_.style.left=t.left+t.width+10+"px":this.element_.classList.contains(this.CssClasses_.LEFT)?this.element_.style.left=t.left-this.element_.offsetWidth-10+"px":this.element_.style.top=t.top+t.height+10+"px",this.element_.classList.add(this.CssClasses_.IS_ACTIVE)},f.prototype.hideTooltip_=function(){this.element_.classList.remove(this.CssClasses_.IS_ACTIVE)},f.prototype.init=function(){if(this.element_){var e=this.element_.getAttribute("for")||this.element_.getAttribute("data-mdl-for");e&&(this.forElement_=document.getElementById(e)),this.forElement_&&(this.forElement_.hasAttribute("tabindex")||this.forElement_.setAttribute("tabindex","0"),this.boundMouseEnterHandler=this.handleMouseEnter_.bind(this),this.boundMouseLeaveAndScrollHandler=this.hideTooltip_.bind(this),this.forElement_.addEventListener("mouseenter",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("touchend",this.boundMouseEnterHandler,!1),this.forElement_.addEventListener("mouseleave",this.boundMouseLeaveAndScrollHandler,!1),window.addEventListener("scroll",this.boundMouseLeaveAndScrollHandler,!0),window.addEventListener("touchstart",this.boundMouseLeaveAndScrollHandler))}},i.register({constructor:f,classAsString:"MaterialTooltip",cssClass:"mdl-tooltip"});var b=function(e){this.element_=e,this.init()};window.MaterialLayout=b,b.prototype.Constant_={MAX_WIDTH:"(max-width: 1024px)",TAB_SCROLL_PIXELS:100,RESIZE_TIMEOUT:100,MENU_ICON:"",CHEVRON_LEFT:"chevron_left",CHEVRON_RIGHT:"chevron_right"},b.prototype.Keycodes_={ENTER:13,ESCAPE:27,SPACE:32},b.prototype.Mode_={STANDARD:0,SEAMED:1,WATERFALL:2,SCROLL:3},b.prototype.CssClasses_={CONTAINER:"mdl-layout__container",HEADER:"mdl-layout__header",DRAWER:"mdl-layout__drawer",CONTENT:"mdl-layout__content",DRAWER_BTN:"mdl-layout__drawer-button",ICON:"material-icons",JS_RIPPLE_EFFECT:"mdl-js-ripple-effect",RIPPLE_CONTAINER:"mdl-layout__tab-ripple-container",RIPPLE:"mdl-ripple",RIPPLE_IGNORE_EVENTS:"mdl-js-ripple-effect--ignore-events",HEADER_SEAMED:"mdl-layout__header--seamed",HEADER_WATERFALL:"mdl-layout__header--waterfall",HEADER_SCROLL:"mdl-layout__header--scroll",FIXED_HEADER:"mdl-layout--fixed-header",OBFUSCATOR:"mdl-layout__obfuscator",TAB_BAR:"mdl-layout__tab-bar",TAB_CONTAINER:"mdl-layout__tab-bar-container",TAB:"mdl-layout__tab",TAB_BAR_BUTTON:"mdl-layout__tab-bar-button",TAB_BAR_LEFT_BUTTON:"mdl-layout__tab-bar-left-button",TAB_BAR_RIGHT_BUTTON:"mdl-layout__tab-bar-right-button",TAB_MANUAL_SWITCH:"mdl-layout__tab-manual-switch",PANEL:"mdl-layout__tab-panel",HAS_DRAWER:"has-drawer",HAS_TABS:"has-tabs",HAS_SCROLLING_HEADER:"has-scrolling-header",CASTING_SHADOW:"is-casting-shadow",IS_COMPACT:"is-compact",IS_SMALL_SCREEN:"is-small-screen",IS_DRAWER_OPEN:"is-visible",IS_ACTIVE:"is-active",IS_UPGRADED:"is-upgraded",IS_ANIMATING:"is-animating",ON_LARGE_SCREEN:"mdl-layout--large-screen-only",ON_SMALL_SCREEN:"mdl-layout--small-screen-only"},b.prototype.contentScrollHandler_=function(){if(!this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)){var e=!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN)||this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);this.content_.scrollTop>0&&!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)?(this.header_.classList.add(this.CssClasses_.CASTING_SHADOW),this.header_.classList.add(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING)):this.content_.scrollTop<=0&&this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW),this.header_.classList.remove(this.CssClasses_.IS_COMPACT),e&&this.header_.classList.add(this.CssClasses_.IS_ANIMATING))}},b.prototype.keyboardEventHandler_=function(e){e.keyCode===this.Keycodes_.ESCAPE&&this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)&&this.toggleDrawer()},b.prototype.screenSizeHandler_=function(){this.screenSizeMediaQuery_.matches?this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN):(this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN),this.drawer_&&(this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN),this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN)))},b.prototype.drawerToggleHandler_=function(e){if(e&&"keydown"===e.type){if(e.keyCode!==this.Keycodes_.SPACE&&e.keyCode!==this.Keycodes_.ENTER)return;e.preventDefault()}this.toggleDrawer()},b.prototype.headerTransitionEndHandler_=function(){this.header_.classList.remove(this.CssClasses_.IS_ANIMATING)},b.prototype.headerClickHandler_=function(){this.header_.classList.contains(this.CssClasses_.IS_COMPACT)&&(this.header_.classList.remove(this.CssClasses_.IS_COMPACT),this.header_.classList.add(this.CssClasses_.IS_ANIMATING))},b.prototype.resetTabState_=function(e){for(var t=0;t0?c.classList.add(this.CssClasses_.IS_ACTIVE):c.classList.remove(this.CssClasses_.IS_ACTIVE),this.tabBar_.scrollLeft0)return;this.setFrameCount(1);var s,i,n=e.currentTarget.getBoundingClientRect();if(0===e.clientX&&0===e.clientY)s=Math.round(n.width/2),i=Math.round(n.height/2);else{var a=void 0!==e.clientX?e.clientX:e.touches[0].clientX,l=void 0!==e.clientY?e.clientY:e.touches[0].clientY;s=Math.round(a-n.left),i=Math.round(l-n.top)}this.setRippleXY(s,i),this.setRippleStyles(!0),window.requestAnimationFrame(this.animFrameHandler.bind(this))}},y.prototype.upHandler_=function(e){e&&2!==e.detail&&window.setTimeout(function(){this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE)}.bind(this),0)},y.prototype.init=function(){if(this.element_){var e=this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)||(this.rippleElement_=this.element_.querySelector("."+this.CssClasses_.RIPPLE),this.frameCount_=0,this.rippleSize_=0,this.x_=0,this.y_=0,this.ignoringMouseDown_=!1,this.boundDownHandler=this.downHandler_.bind(this),this.element_.addEventListener("mousedown",this.boundDownHandler),this.element_.addEventListener("touchstart",this.boundDownHandler),this.boundUpHandler=this.upHandler_.bind(this),this.element_.addEventListener("mouseup",this.boundUpHandler),this.element_.addEventListener("mouseleave",this.boundUpHandler),this.element_.addEventListener("touchend",this.boundUpHandler),this.element_.addEventListener("blur",this.boundUpHandler),this.getFrameCount=function(){return this.frameCount_},this.setFrameCount=function(e){this.frameCount_=e},this.getRippleElement=function(){return this.rippleElement_},this.setRippleXY=function(e,t){this.x_=e,this.y_=t},this.setRippleStyles=function(t){if(null!==this.rippleElement_){var s,i,n="translate("+this.x_+"px, "+this.y_+"px)";t?(i=this.Constant_.INITIAL_SCALE,this.Constant_.INITIAL_SIZE):(i=this.Constant_.FINAL_SCALE,this.rippleSize_+"px",e&&(n="translate("+this.boundWidth/2+"px, "+this.boundHeight/2+"px)")),s="translate(-50%, -50%) "+n+i,this.rippleElement_.style.webkitTransform=s,this.rippleElement_.style.msTransform=s,this.rippleElement_.style.transform=s,t?this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING):this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING)}},this.animFrameHandler=function(){this.frameCount_-- >0?window.requestAnimationFrame(this.animFrameHandler.bind(this)):this.setRippleStyles(!1)})}},i.register({constructor:y,classAsString:"MaterialRipple",cssClass:"mdl-js-ripple-effect",widget:!1})}(); -},{}],"8QiI":[function(require,module,exports) { +},{}],"QiIT":[function(require,module,exports) { var e=module.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e); -},{}],"k/OQ":[function(require,module,exports) { +},{}],"kOQz":[function(require,module,exports) { var r={}.hasOwnProperty;module.exports=function(e,n){return r.call(e,n)}; },{}],"BI7s":[function(require,module,exports) { module.exports=function(r){try{return!!r()}catch(t){return!0}}; },{}],"jVdc":[function(require,module,exports) { module.exports=!require("./_fails")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}); -},{"./_fails":"BI7s"}],"6DcE":[function(require,module,exports) { -var e=module.exports={version:"2.6.9"};"number"==typeof __e&&(__e=e); -},{}],"/2t/":[function(require,module,exports) { +},{"./_fails":"BI7s"}],"DcE6":[function(require,module,exports) { +var e=module.exports={version:"2.6.11"};"number"==typeof __e&&(__e=e); +},{}],"tZ11":[function(require,module,exports) { module.exports=function(o){return"object"==typeof o?null!==o:"function"==typeof o}; -},{}],"1087":[function(require,module,exports) { +},{}],"AIrJ":[function(require,module,exports) { var r=require("./_is-object");module.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}; -},{"./_is-object":"/2t/"}],"4cz6":[function(require,module,exports) { +},{"./_is-object":"tZ11"}],"cz6Q":[function(require,module,exports) { var e=require("./_is-object"),r=require("./_global").document,t=e(r)&&e(r.createElement);module.exports=function(e){return t?r.createElement(e):{}}; -},{"./_is-object":"/2t/","./_global":"8QiI"}],"+9/k":[function(require,module,exports) { +},{"./_is-object":"tZ11","./_global":"QiIT"}],"kIpn":[function(require,module,exports) { module.exports=!require("./_descriptors")&&!require("./_fails")(function(){return 7!=Object.defineProperty(require("./_dom-create")("div"),"a",{get:function(){return 7}}).a}); -},{"./_descriptors":"jVdc","./_fails":"BI7s","./_dom-create":"4cz6"}],"S7GM":[function(require,module,exports) { +},{"./_descriptors":"jVdc","./_fails":"BI7s","./_dom-create":"cz6Q"}],"S7GM":[function(require,module,exports) { var t=require("./_is-object");module.exports=function(r,e){if(!t(r))return r;var o,n;if(e&&"function"==typeof(o=r.toString)&&!t(n=o.call(r)))return n;if("function"==typeof(o=r.valueOf)&&!t(n=o.call(r)))return n;if(!e&&"function"==typeof(o=r.toString)&&!t(n=o.call(r)))return n;throw TypeError("Can't convert object to primitive value")}; -},{"./_is-object":"/2t/"}],"gGgn":[function(require,module,exports) { +},{"./_is-object":"tZ11"}],"gGgn":[function(require,module,exports) { var e=require("./_an-object"),r=require("./_ie8-dom-define"),t=require("./_to-primitive"),i=Object.defineProperty;exports.f=require("./_descriptors")?Object.defineProperty:function(o,n,u){if(e(o),n=t(n,!0),e(u),r)try{return i(o,n,u)}catch(c){}if("get"in u||"set"in u)throw TypeError("Accessors not supported!");return"value"in u&&(o[n]=u.value),o}; -},{"./_an-object":"1087","./_ie8-dom-define":"+9/k","./_to-primitive":"S7GM","./_descriptors":"jVdc"}],"zQQJ":[function(require,module,exports) { +},{"./_an-object":"AIrJ","./_ie8-dom-define":"kIpn","./_to-primitive":"S7GM","./_descriptors":"jVdc"}],"zQQJ":[function(require,module,exports) { module.exports=function(e,r){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:r}}; },{}],"nCfi":[function(require,module,exports) { var r=require("./_object-dp"),e=require("./_property-desc");module.exports=require("./_descriptors")?function(t,u,o){return r.f(t,u,e(1,o))}:function(r,e,t){return r[e]=t,r}; @@ -36,186 +38,186 @@ module.exports=!1; },{}],"k492":[function(require,module,exports) { var r=require("./_core"),e=require("./_global"),o="__core-js_shared__",i=e[o]||(e[o]={});(module.exports=function(r,e){return i[r]||(i[r]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:require("./_library")?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"}); -},{"./_core":"6DcE","./_global":"8QiI","./_library":"dG4y"}],"it4f":[function(require,module,exports) { +},{"./_core":"DcE6","./_global":"QiIT","./_library":"dG4y"}],"it4f":[function(require,module,exports) { module.exports=require("./_shared")("native-function-to-string",Function.toString); },{"./_shared":"k492"}],"jDrK":[function(require,module,exports) { var e=require("./_global"),r=require("./_hide"),t=require("./_has"),i=require("./_uid")("src"),n=require("./_function-to-string"),o="toString",u=(""+n).split(o);require("./_core").inspectSource=function(e){return n.call(e)},(module.exports=function(n,o,c,l){var s="function"==typeof c;s&&(t(c,"name")||r(c,"name",o)),n[o]!==c&&(s&&(t(c,i)||r(c,i,n[o]?""+n[o]:u.join(String(o)))),n===e?n[o]=c:l?n[o]?n[o]=c:r(n,o,c):(delete n[o],r(n,o,c)))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||n.call(this)}); -},{"./_global":"8QiI","./_hide":"nCfi","./_has":"k/OQ","./_uid":"jLFM","./_function-to-string":"it4f","./_core":"6DcE"}],"QKlW":[function(require,module,exports) { +},{"./_global":"QiIT","./_hide":"nCfi","./_has":"kOQz","./_uid":"jLFM","./_function-to-string":"it4f","./_core":"DcE6"}],"QKlW":[function(require,module,exports) { module.exports=function(o){if("function"!=typeof o)throw TypeError(o+" is not a function!");return o}; },{}],"W8bf":[function(require,module,exports) { var r=require("./_a-function");module.exports=function(n,t,u){if(r(n),void 0===t)return n;switch(u){case 1:return function(r){return n.call(t,r)};case 2:return function(r,u){return n.call(t,r,u)};case 3:return function(r,u,e){return n.call(t,r,u,e)}}return function(){return n.apply(t,arguments)}}; },{"./_a-function":"QKlW"}],"Vobs":[function(require,module,exports) { var e=require("./_global"),r=require("./_core"),o=require("./_hide"),i=require("./_redefine"),u=require("./_ctx"),n="prototype",t=function(c,f,l){var q,_,a,d,p=c&t.F,v=c&t.G,F=c&t.S,x=c&t.P,y=c&t.B,B=v?e:F?e[f]||(e[f]={}):(e[f]||{})[n],G=v?r:r[f]||(r[f]={}),P=G[n]||(G[n]={});for(q in v&&(l=f),l)a=((_=!p&&B&&void 0!==B[q])?B:l)[q],d=y&&_?u(a,e):x&&"function"==typeof a?u(Function.call,a):a,B&&i(B,q,a,c&t.U),G[q]!=a&&o(G,q,d),x&&P[q]!=a&&(P[q]=a)};e.core=r,t.F=1,t.G=2,t.S=4,t.P=8,t.B=16,t.W=32,t.U=64,t.R=128,module.exports=t; -},{"./_global":"8QiI","./_core":"6DcE","./_hide":"nCfi","./_redefine":"jDrK","./_ctx":"W8bf"}],"nxhn":[function(require,module,exports) { +},{"./_global":"QiIT","./_core":"DcE6","./_hide":"nCfi","./_redefine":"jDrK","./_ctx":"W8bf"}],"nxhn":[function(require,module,exports) { var e=require("./_uid")("meta"),r=require("./_is-object"),t=require("./_has"),n=require("./_object-dp").f,i=0,u=Object.isExtensible||function(){return!0},f=!require("./_fails")(function(){return u(Object.preventExtensions({}))}),o=function(r){n(r,e,{value:{i:"O"+ ++i,w:{}}})},s=function(n,i){if(!r(n))return"symbol"==typeof n?n:("string"==typeof n?"S":"P")+n;if(!t(n,e)){if(!u(n))return"F";if(!i)return"E";o(n)}return n[e].i},c=function(r,n){if(!t(r,e)){if(!u(r))return!0;if(!n)return!1;o(r)}return r[e].w},E=function(r){return f&&a.NEED&&u(r)&&!t(r,e)&&o(r),r},a=module.exports={KEY:e,NEED:!1,fastKey:s,getWeak:c,onFreeze:E}; -},{"./_uid":"jLFM","./_is-object":"/2t/","./_has":"k/OQ","./_object-dp":"gGgn","./_fails":"BI7s"}],"I5XL":[function(require,module,exports) { +},{"./_uid":"jLFM","./_is-object":"tZ11","./_has":"kOQz","./_object-dp":"gGgn","./_fails":"BI7s"}],"I5XL":[function(require,module,exports) { var e=require("./_shared")("wks"),r=require("./_uid"),o=require("./_global").Symbol,u="function"==typeof o,i=module.exports=function(i){return e[i]||(e[i]=u&&o[i]||(u?o:r)("Symbol."+i))};i.store=e; -},{"./_shared":"k492","./_uid":"jLFM","./_global":"8QiI"}],"+IBD":[function(require,module,exports) { +},{"./_shared":"k492","./_uid":"jLFM","./_global":"QiIT"}],"IBDH":[function(require,module,exports) { var e=require("./_object-dp").f,r=require("./_has"),o=require("./_wks")("toStringTag");module.exports=function(t,u,i){t&&!r(t=i?t:t.prototype,o)&&e(t,o,{configurable:!0,value:u})}; -},{"./_object-dp":"gGgn","./_has":"k/OQ","./_wks":"I5XL"}],"Jnk4":[function(require,module,exports) { +},{"./_object-dp":"gGgn","./_has":"kOQz","./_wks":"I5XL"}],"Jnk4":[function(require,module,exports) { exports.f=require("./_wks"); },{"./_wks":"I5XL"}],"ZenZ":[function(require,module,exports) { var r=require("./_global"),e=require("./_core"),o=require("./_library"),i=require("./_wks-ext"),l=require("./_object-dp").f;module.exports=function(u){var a=e.Symbol||(e.Symbol=o?{}:r.Symbol||{});"_"==u.charAt(0)||u in a||l(a,u,{value:i.f(u)})}; -},{"./_global":"8QiI","./_core":"6DcE","./_library":"dG4y","./_wks-ext":"Jnk4","./_object-dp":"gGgn"}],"3+Dr":[function(require,module,exports) { +},{"./_global":"QiIT","./_core":"DcE6","./_library":"dG4y","./_wks-ext":"Jnk4","./_object-dp":"gGgn"}],"DrRY":[function(require,module,exports) { var r={}.toString;module.exports=function(t){return r.call(t).slice(8,-1)}; },{}],"sUp0":[function(require,module,exports) { var e=require("./_cof");module.exports=Object("z").propertyIsEnumerable(0)?Object:function(r){return"String"==e(r)?r.split(""):Object(r)}; -},{"./_cof":"3+Dr"}],"3V0R":[function(require,module,exports) { +},{"./_cof":"DrRY"}],"V0RG":[function(require,module,exports) { module.exports=function(o){if(null==o)throw TypeError("Can't call method on "+o);return o}; },{}],"zakI":[function(require,module,exports) { var e=require("./_iobject"),r=require("./_defined");module.exports=function(i){return e(r(i))}; -},{"./_iobject":"sUp0","./_defined":"3V0R"}],"ubM9":[function(require,module,exports) { +},{"./_iobject":"sUp0","./_defined":"V0RG"}],"ubM9":[function(require,module,exports) { var o=Math.ceil,r=Math.floor;module.exports=function(t){return isNaN(t=+t)?0:(t>0?r:o)(t)}; -},{}],"0KLz":[function(require,module,exports) { +},{}],"KLzx":[function(require,module,exports) { var e=require("./_to-integer"),r=Math.min;module.exports=function(t){return t>0?r(e(t),9007199254740991):0}; },{"./_to-integer":"ubM9"}],"tPLG":[function(require,module,exports) { var e=require("./_to-integer"),r=Math.max,t=Math.min;module.exports=function(n,a){return(n=e(n))<0?r(n+a,0):t(n,a)}; },{"./_to-integer":"ubM9"}],"ntLR":[function(require,module,exports) { var e=require("./_to-iobject"),r=require("./_to-length"),t=require("./_to-absolute-index");module.exports=function(n){return function(i,o,u){var f,l=e(i),a=r(l.length),c=t(u,a);if(n&&o!=o){for(;a>c;)if((f=l[c++])!=f)return!0}else for(;a>c;c++)if((n||c in l)&&l[c]===o)return n||c||0;return!n&&-1}}; -},{"./_to-iobject":"zakI","./_to-length":"0KLz","./_to-absolute-index":"tPLG"}],"4UE8":[function(require,module,exports) { +},{"./_to-iobject":"zakI","./_to-length":"KLzx","./_to-absolute-index":"tPLG"}],"UE8F":[function(require,module,exports) { var e=require("./_shared")("keys"),r=require("./_uid");module.exports=function(u){return e[u]||(e[u]=r(u))}; },{"./_shared":"k492","./_uid":"jLFM"}],"tBLI":[function(require,module,exports) { var r=require("./_has"),e=require("./_to-iobject"),u=require("./_array-includes")(!1),i=require("./_shared-key")("IE_PROTO");module.exports=function(o,a){var n,s=e(o),t=0,h=[];for(n in s)n!=i&&r(s,n)&&h.push(n);for(;a.length>t;)r(s,n=a[t++])&&(~u(h,n)||h.push(n));return h}; -},{"./_has":"k/OQ","./_to-iobject":"zakI","./_array-includes":"ntLR","./_shared-key":"4UE8"}],"qGBL":[function(require,module,exports) { +},{"./_has":"kOQz","./_to-iobject":"zakI","./_array-includes":"ntLR","./_shared-key":"UE8F"}],"qGBL":[function(require,module,exports) { module.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","); -},{}],"+huX":[function(require,module,exports) { +},{}],"huXi":[function(require,module,exports) { var e=require("./_object-keys-internal"),r=require("./_enum-bug-keys");module.exports=Object.keys||function(u){return e(u,r)}; },{"./_object-keys-internal":"tBLI","./_enum-bug-keys":"qGBL"}],"vSss":[function(require,module,exports) { exports.f=Object.getOwnPropertySymbols; },{}],"NRj4":[function(require,module,exports) { exports.f={}.propertyIsEnumerable; -},{}],"6BDX":[function(require,module,exports) { +},{}],"BDXu":[function(require,module,exports) { var e=require("./_object-keys"),r=require("./_object-gops"),o=require("./_object-pie");module.exports=function(t){var u=e(t),i=r.f;if(i)for(var c,f=i(t),a=o.f,l=0;f.length>l;)a.call(t,c=f[l++])&&u.push(c);return u}; -},{"./_object-keys":"+huX","./_object-gops":"vSss","./_object-pie":"NRj4"}],"JI5q":[function(require,module,exports) { +},{"./_object-keys":"huXi","./_object-gops":"vSss","./_object-pie":"NRj4"}],"JI5q":[function(require,module,exports) { var r=require("./_cof");module.exports=Array.isArray||function(e){return"Array"==r(e)}; -},{"./_cof":"3+Dr"}],"2XMZ":[function(require,module,exports) { +},{"./_cof":"DrRY"}],"XMZs":[function(require,module,exports) { var e=require("./_defined");module.exports=function(r){return Object(e(r))}; -},{"./_defined":"3V0R"}],"L4n9":[function(require,module,exports) { +},{"./_defined":"V0RG"}],"L4n9":[function(require,module,exports) { var e=require("./_object-dp"),r=require("./_an-object"),t=require("./_object-keys");module.exports=require("./_descriptors")?Object.defineProperties:function(o,i){r(o);for(var u,c=t(i),n=c.length,s=0;n>s;)e.f(o,u=c[s++],i[u]);return o}; -},{"./_object-dp":"gGgn","./_an-object":"1087","./_object-keys":"+huX","./_descriptors":"jVdc"}],"HDWL":[function(require,module,exports) { +},{"./_object-dp":"gGgn","./_an-object":"AIrJ","./_object-keys":"huXi","./_descriptors":"jVdc"}],"HDWL":[function(require,module,exports) { var e=require("./_global").document;module.exports=e&&e.documentElement; -},{"./_global":"8QiI"}],"EH/8":[function(require,module,exports) { +},{"./_global":"QiIT"}],"EH8e":[function(require,module,exports) { var e=require("./_an-object"),r=require("./_object-dps"),t=require("./_enum-bug-keys"),n=require("./_shared-key")("IE_PROTO"),o=function(){},i="prototype",u=function(){var e,r=require("./_dom-create")("iframe"),n=t.length;for(r.style.display="none",require("./_html").appendChild(r),r.src="javascript:",(e=r.contentWindow.document).open(),e.write("