Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,5 @@ Win32
*.dir
perf
nnvm
*.wasm
.emscripten
37 changes: 37 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ stage('Build') {
pack_lib('i386')
}
}
},
'web': {
node('emcc') {
ws('workspace/tvm/build-weblib') {
init_git()
sh """
cp make/config.mk .
echo USE_CUDA=0 >> config.mk
echo USE_OPENCL=0 >> config.mk
echo LLVM_CONFIG=llvm-config >> config.mk
echo USE_RPC=0 >> config.mk
"""
sh "${docker_run} emscripten echo testing javascript..."
timeout(time: max_time, unit: 'MINUTES') {
try {
sh "${docker_run} emscripten ./tests/scripts/task_web_build.sh"
} catch (exc) {
echo 'Incremental compilation failed. Fall back to build from scratch'
sh "${docker_run} emscripten make clean"
sh "${docker_run} emscripten ./tests/scripts/task_web_build.sh"
}
}
pack_lib('weblib')
}
}
}
}

Expand Down Expand Up @@ -174,6 +199,18 @@ stage('Integration Test') {
}
}
},
'web': {
node('emcc') {
ws('workspace/tvm/it-weblib') {
init_git()
unpack_lib('weblib')
sh "${docker_run} emscripten echo testing javascript..."
timeout(time: max_time, unit: 'MINUTES') {
sh "${docker_run} emscripten ./tests/scripts/task_web_test.sh"
}
}
}
},
'docs': {
node('GPU' && 'linux') {
ws('workspace/tvm/docs-python-gpu') {
Expand Down
18 changes: 15 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ endif

include $(config)

.PHONY: clean all test doc pylint cpplint lint verilog cython cython2 cython3
.PHONY: clean all test doc pylint cpplint lint verilog cython cython2 cython3 web runtime

BUILD_TARGETS ?= lib/libtvm.so lib/libtvm_runtime.so
all: ${BUILD_TARGETS}
runtime: lib/libtvm_runtime.so
web: lib/libtvm_web_runtime.js lib/libtvm_web_runtime.bc

ifndef DMLC_CORE_PATH
DMLC_CORE_PATH = $(ROOTDIR)/dmlc-core
Expand Down Expand Up @@ -52,11 +53,13 @@ RUNTIME_DEP = $(RUNTIME_OBJ)

# The flags
LDFLAGS = -pthread -lm -ldl
CFLAGS = -std=c++11 -Wall -O2\
-Iinclude -I$(DLPACK_PATH)/include -I$(DMLC_CORE_PATH)/include -IHalideIR/src -Itopi/include -fPIC
INCLUDE_FLAGS = -Iinclude -I$(DLPACK_PATH)/include -I$(DMLC_CORE_PATH)/include -IHalideIR/src -Itopi/include
CFLAGS = -std=c++11 -Wall -O2 $(INCLUDE_FLAGS) -fPIC
LLVM_CFLAGS= -fno-rtti -DDMLC_ENABLE_RTTI=0
FRAMEWORKS =
OBJCFLAGS = -fno-objc-arc
EMCC_FLAGS= -s RESERVED_FUNCTION_POINTERS=2 -s NO_EXIT_RUNTIME=1 -DDMLC_LOG_STACK_TRACE=0\
-std=c++11 -Oz $(INCLUDE_FLAGS)

# Dependency specific rules
ifdef CUDA_PATH
Expand Down Expand Up @@ -149,6 +152,15 @@ lib/libtvm_runtime.so: $(RUNTIME_DEP)
@mkdir -p $(@D)
$(CXX) $(CFLAGS) $(FRAMEWORKS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)

lib/libtvm_web_runtime.bc: web/web_runtime.cc
@mkdir -p build/web
@mkdir -p $(@D)
$(CXX) $(CFLAGS) -MM -MT lib/libtvm_web_runtime.bc $< >build/web/web_runtime.d
emcc $(EMCC_FLAGS) -o $@ web/web_runtime.cc

lib/libtvm_web_runtime.js: lib/libtvm_web_runtime.bc
@mkdir -p $(@D)
emcc $(EMCC_FLAGS) -o $@ lib/libtvm_web_runtime.bc

$(LIB_HALIDEIR): LIBHALIDEIR

Expand Down
7 changes: 7 additions & 0 deletions docs/api_links.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Links to API References
=======================

This page contains links to API references that are build with different doc build system.

* `C++ doyxgen API <doxygen/index.html>`_
* `Javascript jsdoc API <jsdoc/index.html>`_
9 changes: 4 additions & 5 deletions docs/how_to/contribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
TVM has been developed by community members.
Everyone is more than welcome to contribute. It is a way to make the project better and more accessible to more users.

- Please add your name to [CONTRIBUTORS.md](../../CONTRIBUTORS.md)
- Please update [NEWS.md](../../NEWS.md) to add note on your changes to the API or added a new document.
- Please add your name to [CONTRIBUTORS.md](https://github.com/dmlc/tvm/blob/master/CONTRIBUTORS.md)
- Please update [NEWS.md](https://github.com/dmlc/tvm/blob/master/NEWS.md) to add note on your changes to the API or added a new document.

## Guidelines
* [Submit Pull Request](#submit-pull-request)
Expand All @@ -29,7 +29,7 @@ git rebase upstream/master
it might be good to merge them together(use git rebase then squash) into more meaningful groups.
* Send the pull request!
- Fix the problems reported by automatic checks
- If you are contributing a new module, consider add a testcase in [tests](../tests)
- If you are contributing a new module or new function, add a test.

## Git Workflow Howtos
### How to resolve conflict with master
Expand Down Expand Up @@ -87,8 +87,7 @@ The previous two tips requires force push, this is because we altered the path o
It is fine to force push to your own fork, as long as the commits changed are only yours.

## Testcases
- All the testcases are in [tests](../../tests)
- We use python nose for python test cases.
- All the testcases are in tests

## Core Library
- Follow Google C style for C++.
Expand Down
8 changes: 4 additions & 4 deletions docs/how_to/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ You can edit `make/config.mk` to change the compile options, and then build by
### Building on Windows

TVM support build via MSVC using cmake. To build with Visual Studio 2015 use cmake.
Make sure you have a recent version of cmake added to your path and then from the xgboost directory:
Make sure you have a recent version of cmake added to your path and then from the tvm directory:

```bash
mkdir build
Expand All @@ -46,16 +46,16 @@ This specifies an out of source build using the MSVC 12 64 bit generator. Open t

### Customized Building

The configuration of xgboost can be modified by ```config.mk```
- First copy [make/config.mk](../make/config.mk) to the project root, on which
The configuration of tvm can be modified by ```config.mk```
- First copy make/config.mk to the project root, on which
any local modification will be ignored by git, then modify the according flags.
- TVM optionally depends on LLVM. LLVM is required for CPU codegen that needs LLVM.
- LLVM 4.0 is needed for build with LLVM
- By default CUDA and OpenCL code generator do not require llvm.

## Python Package Installation

The python package is located at [python](../python).
The python package is located at python
There are several ways to install the package:

1. Set the environment variable `PYTHONPATH` to tell python where to find
Expand Down
4 changes: 3 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ TVM Documentation

Welcome to TVM documentation.


Contents
--------

Expand All @@ -13,6 +14,7 @@ Contents
how_to/install
tutorials/index
faq
api/python/index
how_to/contribute
api/python/index
api_links
genindex
10 changes: 8 additions & 2 deletions include/tvm/runtime/c_runtime_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
#define TVM_EXTERN_C
#endif

/*! \brief TVM_DLL prefix for windows */
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#define TVM_DLL EMSCRIPTEN_KEEPALIVE
#endif

#ifndef TVM_DLL
#ifdef _WIN32
#ifdef TVM_EXPORTS
#define TVM_DLL __declspec(dllexport)
Expand All @@ -34,6 +39,7 @@
#else
#define TVM_DLL
#endif
#endif

// TVM Runtime is DLPack compatible.
#include <dlpack/dlpack.h>
Expand Down Expand Up @@ -331,7 +337,7 @@ TVM_DLL int TVMFuncGetGlobal(const char* name, TVMFunctionHandle* out);
* \param out_array The array of function names.
* \return 0 when success, -1 when failure happens
*/
TVM_DLL int TVMFuncListGlobalNames(int *out_size,
TVM_DLL int TVMFuncListGlobalNames(int* out_size,
const char*** out_array);

// Array related apis for quick proptyping
Expand Down
1 change: 1 addition & 0 deletions python/tvm/_ffi/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class TVMError(Exception):
"""Error thrown by TVM function"""
pass


def _load_lib():
"""Load libary by searching possible path."""
lib_path = libinfo.find_lib_path()
Expand Down
22 changes: 15 additions & 7 deletions python/tvm/_ffi/libinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
import platform


def find_lib_path():
def find_lib_path(name=None):
"""Find dynamic library files.

Parameters
----------
name : list of str
List of names to be found.

Returns
-------
lib_path : list(string)
Expand All @@ -30,13 +35,16 @@ def find_lib_path():
elif os.name == "posix" and os.environ.get('LD_LIBRARY_PATH', None):
dll_path.extend([p.strip() for p in os.environ['LD_LIBRARY_PATH'].split(":")])
dll_path = [os.path.abspath(x) for x in dll_path]

if os.name == 'nt':
lib_dll_path = [os.path.join(p, 'libtvm.dll') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.dll') for p in dll_path]
if name is not None:
lib_dll_path = [os.path.join(p, name) for p in dll_path]
runtime_dll_path = []
else:
lib_dll_path = [os.path.join(p, 'libtvm.so') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.so') for p in dll_path]
if os.name == 'nt':
lib_dll_path = [os.path.join(p, 'libtvm.dll') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.dll') for p in dll_path]
else:
lib_dll_path = [os.path.join(p, 'libtvm.so') for p in dll_path]
runtime_dll_path = [os.path.join(p, 'libtvm_runtime.so') for p in dll_path]

if not use_runtime:
# try to find lib_dll_path
Expand Down
57 changes: 57 additions & 0 deletions python/tvm/contrib/emscripten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Util to invoke emscripten compilers in the system."""
# pylint: disable=invalid-name
from __future__ import absolute_import as _abs
import subprocess
from .._ffi.libinfo import find_lib_path

def create_js(output,
objects,
options=None,
cc="emcc"):
"""Create emscripten javascript library.

Parameters
----------
output : str
The target shared library.

objects : list
List of object files.

options : str
The additional options.

cc : str, optional
The compile string.
"""
cmd = [cc]
cmd += ["-s", "RESERVED_FUNCTION_POINTERS=2"]
cmd += ["-s", "NO_EXIT_RUNTIME=1"]
cmd += ["-Oz"]
cmd += ["-o", output]

objects = [objects] if isinstance(objects, str) else objects
with_runtime = False
for obj in objects:
if obj.find("libtvm_web_runtime.bc") != -1:
with_runtime = True

if not with_runtime:
objects += [find_lib_path("libtvm_web_runtime.bc")[0]]

cmd += objects

if options:
cmd += options

args = ' '.join(cmd)
proc = subprocess.Popen(
args, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(out, _) = proc.communicate()

if proc.returncode != 0:
msg = "Compilation error:\n"
msg += out
raise RuntimeError(msg)
9 changes: 7 additions & 2 deletions src/codegen/llvm/llvm_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void InitializeLLVM() {
}

llvm::TargetMachine*
GetLLVMTargetMachine(const std::string& target_str) {
GetLLVMTargetMachine(const std::string& target_str, bool allow_null) {
// setup target triple
CHECK(target_str.length() >= 4 &&
target_str.substr(0, 4) == "llvm")
Expand Down Expand Up @@ -91,7 +91,10 @@ GetLLVMTargetMachine(const std::string& target_str) {
std::string err;
const llvm::Target* target =
llvm::TargetRegistry::lookupTarget(target_triple, err);
CHECK(target) << err << " target_triple=" << target_triple;
if (target == nullptr) {
CHECK(allow_null) << err << " target_triple=" << target_triple;
return nullptr;
}
// set target option
llvm::TargetOptions opt;
opt.LessPreciseFPMADOption = true;
Expand All @@ -110,6 +113,8 @@ GetLLVMTargetMachine(const std::string& target_str) {
return tm;
}



} // namespace codegen
} // namespace tvm
#endif // TVM_LLVM_VERSION
4 changes: 2 additions & 2 deletions src/codegen/llvm/llvm_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ void InitializeLLVM();
/*!
* \brief Get target machine from target_str string.
* \param target_str Target string, in format "llvm -target=xxx -mcpu=xxx"
*
* \param allow_null Whether allow null to be returned.
* \return target machine
*/
llvm::TargetMachine*
GetLLVMTargetMachine(const std::string& target_str);
GetLLVMTargetMachine(const std::string& target_str, bool allow_null = false);

} // namespace codegen
} // namespace tvm
Expand Down
6 changes: 6 additions & 0 deletions src/codegen/llvm/llvm_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ TVM_REGISTER_API("module.loadfile_ll")
n->LoadIR(args[0]);
*rv = runtime::Module(n);
});

TVM_REGISTER_API("codegen.llvm_target_enabled")
.set_body([](TVMArgs args, TVMRetValue* rv) {
InitializeLLVM();
*rv = (GetLLVMTargetMachine(args[0], true) != nullptr);
});
} // namespace codegen
} // namespace tvm
#endif // TVM_LLVM_VERSION
6 changes: 4 additions & 2 deletions src/runtime/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,14 @@ bool RuntimeEnabled(const std::string& target) {
f_name = "device_api.metal";
} else if (target == "stackvm") {
f_name = "codegen.build_stackvm";
} else if (target == "llvm") {
f_name = "codegen.build_llvm";
} else if (target == "rpc") {
f_name = "device_api.rpc";
} else if (target == "vpi" || target == "verilog") {
f_name = "device_api.vpi";
} else if (target.length() >= 4 && target.substr(0, 4) == "llvm") {
const PackedFunc* pf = runtime::Registry::Get("codegen.llvm_target_enabled");
if (pf == nullptr) return false;
return (*pf)(target);
} else {
LOG(FATAL) << "Unknown optional runtime " << target;
}
Expand Down
Loading