Unverified Commit ff65698f by Tianqi Chen Committed by GitHub

[DEPRECATION] Cleanup legacy verilog support (#4576)

This PR cleans up the left over code for legacy verilog support which was experimental.
The new hardware backend path is now support by VTA via TSIM.
parent c90160b2
......@@ -168,11 +168,6 @@ endif(USE_VM_PROFILER)
file(GLOB DATATYPE_SRCS src/codegen/datatype/*.cc)
list(APPEND COMPILER_SRCS ${DATATYPE_SRCS})
if(NOT MSVC)
file(GLOB COMPILER_VERILOG_SRCS src/codegen/verilog/*.cc)
list(APPEND COMPILER_SRCS ${COMPILER_VERILOG_SRCS})
endif()
file(GLOB TOPI_SRCS
topi/src/*.cc
......
#!/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.
set -e
set -u
set -o pipefail
apt-get install -y --no-install-recommends make bison flex
wget -q ftp://icarus.com/pub/eda/verilog/v10/verilog-10.1.tar.gz
tar xf verilog-10.1.tar.gz
cd verilog-10.1
./configure --prefix=/usr
make install -j8
cd ..
rm -rf verilog-10.1 verilog-10.1.tar.gz
/*
* 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.
*/
/*!
* \file tvm/channel.h
* \brief Channel object for pipeline.
*/
#ifndef TVM_CHANNEL_H_
#define TVM_CHANNEL_H_
#include <tvm/expr.h>
namespace tvm {
// Node container of channel
struct ChannelNode;
/*! \brief The data channel. */
class Channel : public NodeRef {
public:
/*! \brief default constructor */
Channel() {}
explicit Channel(ObjectPtr<Object> n) : NodeRef(n) {}
/*!
* \brief access the internal node container
* \return the pointer to the internal node container
*/
inline const ChannelNode* operator->() const;
// The container type
using ContainerType = ChannelNode;
};
/*!
* \brief Generalized FIFO channel.
*/
struct ChannelNode : public Node {
/*! \brief Variable to channel handle */
Var handle_var;
/*! \brief default data type in read/write */
DataType dtype;
// visit all attributes
void VisitAttrs(AttrVisitor* v) {
v->Visit("handle_var", &handle_var);
v->Visit("dtype", &dtype);
}
static Channel make(Var handle_var, DataType dtype);
static constexpr const char* _type_key = "Channel";
TVM_DECLARE_NODE_TYPE_INFO(ChannelNode, Node);
};
// Inline implementations
inline const ChannelNode* Channel::operator->() const {
return static_cast<const ChannelNode*>(get());
}
} // namespace tvm
#endif // TVM_CHANNEL_H_
......@@ -237,21 +237,6 @@ bool VerifyCompactBuffer(Stmt stmt);
Stmt RemoveNoOp(Stmt stmt);
/*!
* \brief Split statement into pipeine stages.
* \param stmt The stmt to be splitted
* \param split_load Whether split load into its own stage.
* \return Transformed stmt.
*/
Stmt SplitPipeline(Stmt stmt, bool split_load);
/*!
* \brief Narrow channel access to smaller range.
* \param stmt The stmt to do access rewriting.
* \return Transformed stmt.
*/
Stmt NarrowChannelAccess(Stmt stmt);
/*!
* \brief unroll the constant loop marked by unroll.
* This pass also automatically attach pragma unroll tag to loops which meets the standard.
*
......
# 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.
"""Verilog simulator modules."""
from __future__ import absolute_import
import subprocess
import sys
import os
import ctypes
from .. import _api_internal
from .._ffi.base import string_types
from .._ffi.node import NodeBase, register_node
from .._ffi.function import register_func
from . import util
@register_node
class VPISession(NodeBase):
"""Verilog session"""
def __init__(self, handle):
super(VPISession, self).__init__(handle)
self.proc = None
self.execpath = None
self.yield_callbacks = []
def __del__(self):
self.proc.kill()
try:
super(VPISession, self).__del__()
except AttributeError:
pass
def arg(self, index):
"""Get handle passed to host session.
Parameters
----------
index : int
The index value.
Returns
-------
handle : VPIHandle
The handle
"""
return _api_internal._vpi_SessGetArg(self, index)
def __getitem__(self, name):
if not isinstance(name, string_types):
raise ValueError("have to be string types")
return _api_internal._vpi_SessGetHandleByName(self, name)
def __getattr__(self, name):
return _api_internal._vpi_SessGetHandleByName(self, name)
def yield_until_next_cycle(self):
"""Yield until next posedge"""
for f in self.yield_callbacks:
f()
return _api_internal._vpi_SessYield(self)
def shutdown(self):
"""Shutdown the simulator"""
return _api_internal._vpi_SessShutdown(self)
@register_node
class VPIHandle(NodeBase):
"""Handle to a verilog variable."""
def __init__(self, handle):
super(VPIHandle, self).__init__(handle)
self._name = None
self._size = None
def get_int(self):
"""Get integer value from handle.
Returns
-------
value : int
"""
return _api_internal._vpi_HandleGetInt(self)
def put_int(self, value):
"""Put integer value to handle.
Parameters
----------
value : int
The value to put
"""
return _api_internal._vpi_HandlePutInt(self, value)
@property
def name(self):
if self._name is None:
self._name = _api_internal._vpi_HandleGetName(self)
return self._name
@property
def size(self):
if self._size is None:
self._size = _api_internal._vpi_HandleGetSize(self)
return self._size
def __getitem__(self, name):
if not isinstance(name, string_types):
raise ValueError("have to be string types")
return _api_internal._vpi_HandleGetHandleByName(self, name)
def __getattr__(self, name):
return _api_internal._vpi_HandleGetHandleByName(self, name)
def _find_vpi_path():
curr_path = os.path.dirname(os.path.realpath(os.path.expanduser(__file__)))
api_path = os.path.join(curr_path, '../../../lib/')
vpi_path = [curr_path, api_path]
vpi_path = [os.path.join(p, 'tvm_vpi.vpi') for p in vpi_path]
vpi_found = [p for p in vpi_path if os.path.exists(p) and os.path.isfile(p)]
if vpi_found:
return os.path.dirname(vpi_found[0])
raise ValueError("Cannot find tvm_vpi.vpi, make sure you did `make verilog`")
def search_path():
"""Get the search directory."""
curr_path = os.path.dirname(os.path.realpath(os.path.expanduser(__file__)))
ver_path = [os.path.join(curr_path, '../../../verilog/')]
ver_path += [os.path.join(curr_path, '../../../tests/verilog/unittest/')]
ver_path += [os.path.join(curr_path, '../../../tests/verilog/integration/')]
return ver_path
def find_file(file_name):
"""Find file in the search directories.
Parameters
----------
file_name : str
The file name
Return
------
file_name : str
The absolute path to the file, raise Error if cannot find it.
"""
ver_path = search_path()
flist = [os.path.join(p, file_name) for p in ver_path]
found = [p for p in flist if os.path.exists(p) and os.path.isfile(p)]
if not found:
raise ValueError("Cannot find %s in %s" % (file_name, flist))
return found[0]
def compile_file(file_name, file_target, options=None):
"""Compile verilog via iverilog
Parameters
----------
file_name : str or list of str
The cuda code.
file_target : str
The target file.
"""
cmd = ["iverilog"]
for path in search_path():
cmd += ["-I%s" % path]
cmd += ["-o", file_target]
if options:
cmd += options
if isinstance(file_name, string_types):
file_name = [file_name]
cmd += file_name
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(out, _) = proc.communicate()
if proc.returncode != 0:
raise ValueError("Compilation error:\n%s" % out)
def session(file_names, codes=None):
"""Create a new iverilog session by compile the file.
Parameters
----------
file_names : str or list of str
The name of the file
codes : str or list of str
The code in str.
Returns
-------
sess : VPISession
The created session.
"""
if isinstance(file_names, string_types):
file_names = [file_names]
path = util.tempdir()
if codes:
if isinstance(codes, (list, tuple)):
codes = '\n'.join(codes)
fcode = path.relpath("temp_code.v")
with open(fcode, "w") as out_file:
out_file.write(codes)
file_names.append(fcode)
for name in file_names:
if not os.path.exists(name):
raise ValueError("Cannot find file %s" % name)
target = path.relpath(os.path.basename(file_names[0].rsplit(".", 1)[0]))
compile_file(file_names, target)
vpi_path = _find_vpi_path()
cmd = ["vvp"]
cmd += ["-M", vpi_path]
cmd += ["-m", "tvm_vpi"]
cmd += [target]
env = os.environ.copy()
read_device, write_host = os.pipe()
read_host, write_device = os.pipe()
if sys.platform == "win32":
import msvcrt
env['TVM_DREAD_PIPE'] = str(msvcrt.get_osfhandle(read_device))
env['TVM_DWRITE_PIPE'] = str(msvcrt.get_osfhandle(write_device))
read_host = msvcrt.get_osfhandle(read_host)
write_host = msvcrt.get_osfhandle(write_host)
else:
env['TVM_DREAD_PIPE'] = str(read_device)
env['TVM_DWRITE_PIPE'] = str(write_device)
env['TVM_HREAD_PIPE'] = str(read_host)
env['TVM_HWRITE_PIPE'] = str(write_host)
try:
# close_fds does not work well for all python3
# Use pass_fds instead.
# pylint: disable=unexpected-keyword-arg
pass_fds = (read_device, write_device, read_host, write_host)
proc = subprocess.Popen(cmd, pass_fds=pass_fds, env=env)
except TypeError:
# This is effective for python2
proc = subprocess.Popen(cmd, close_fds=False, env=env)
# close device side pipe
os.close(read_device)
os.close(write_device)
sess = _api_internal._vpi_SessMake(read_host, write_host)
sess.proc = proc
sess.execpath = path
return sess
@register_func
def tvm_callback_verilog_simulator(code, *args):
"""Callback by TVM runtime to invoke verilog simulator
Parameters
----------
code : str
The verilog code to be simulated
args : list
Additional arguments to be set.
"""
libs = [
find_file("tvm_vpi_mmap.v")
]
sess = session(libs, code)
for i, value in enumerate(args):
vpi_h = sess.main["tvm_arg%d" % i]
if isinstance(value, ctypes.c_void_p):
int_value = int(value.value)
elif isinstance(value, int):
int_value = value
else:
raise ValueError(
"Do not know how to handle value type %s" % type(value))
vpi_h.put_int(int_value)
rst = sess.main.rst
done = sess.main.done
# start driving
rst.put_int(1)
sess.yield_until_next_cycle()
rst.put_int(0)
sess.yield_until_next_cycle()
while not done.get_int():
sess.yield_until_next_cycle()
sess.yield_until_next_cycle()
sess.shutdown()
......@@ -159,9 +159,7 @@ REGISTER_PASS(InjectPrefetch);
REGISTER_PASS(InjectDoubleBuffer);
REGISTER_PASS(LoopPartition);
REGISTER_PASS(RemoveNoOp);
REGISTER_PASS(SplitPipeline);
REGISTER_PASS(LiftAttrScope);
REGISTER_PASS(NarrowChannelAccess);
REGISTER_PASS(LowerThreadAllreduce);
REGISTER_PASS(LowerWarpMemory);
REGISTER_PASS(RemapThreadAxis);
......
/*
* 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.
*/
/*!
* \file channel.cc
*/
#include <tvm/channel.h>
namespace tvm {
Channel ChannelNode::make(Var handle_var, DataType dtype) {
auto n = make_node<ChannelNode>();
n->handle_var = handle_var;
n->dtype = dtype;
return Channel(n);
}
TVM_STATIC_IR_FUNCTOR(IRPrinter, vtable)
.set_dispatch<ChannelNode>([](const ObjectRef& node, IRPrinter *p) {
auto* op = static_cast<const ChannelNode*>(node.get());
p->stream << "channel(" << op->handle_var << ", " << op->dtype << ")";
});
TVM_REGISTER_NODE_TYPE(ChannelNode);
} // namespace tvm
/*
* 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.
*/
/*!
* \file narrow_channel_access.cc
* \brief Narrow channel access to a smaller range
* when possible by bringing it to the internal loop.
*/
#include <tvm/ir.h>
#include <tvm/expr.h>
#include <tvm/ir_pass.h>
#include <tvm/ir_visitor.h>
#include <tvm/ir_mutator.h>
#include <tvm/arithmetic.h>
#include <tvm/channel.h>
#include "ir_util.h"
namespace tvm {
namespace ir {
using namespace arith;
// Bound deducer for channel access.
class ChannelAccessBound : public IRVisitor {
public:
ChannelAccessBound(const Variable* buf_var, bool read_access)
: buf_var_(buf_var), read_access_(read_access) {}
void Visit_(const Store* op) final {
if (!read_access_ && buf_var_ == op->buffer_var.get()) {
ret_.emplace_back(EvalSet(op->index, dom_map_));
}
IRVisitor::Visit_(op);
}
void Visit_(const For* op) final {
CHECK(is_zero(op->min));
// We know that the extent of the loop won't depend on relaxed scope.
// TODO(tqchen) have a verification pass.
dom_map_[op->loop_var.get()] = IntSet::interval(op->min, op->extent - 1);
IRVisitor::Visit_(op);
}
void Visit_(const Load* op) final {
if (read_access_ && buf_var_ == op->buffer_var.get()) {
ret_.emplace_back(EvalSet(op->index, dom_map_));
}
IRVisitor::Visit_(op);
}
void Visit_(const Let* op) final {
LOG(FATAL) << "cannot pass through let";
}
void Visit_(const LetStmt* op) final {
LOG(FATAL) << "cannot pass through let";
}
IntSet Eval(const Stmt& stmt) {
Visit(stmt);
return Union(ret_);
}
private:
// The buffer variable.
const Variable* buf_var_;
// read or write
bool read_access_{true};
// Box
std::vector<IntSet> ret_;
// Domain map.
std::unordered_map<const Variable*, IntSet> dom_map_;
};
class ChannelAccessIndexRewriter : public IRMutator {
public:
ChannelAccessIndexRewriter(const Variable* buf_var,
Expr min,
bool read_access)
: buf_var_(buf_var), min_(min), read_access_(read_access) {}
Expr Mutate_(const Load* op, const Expr& e) final {
Expr expr = IRMutator::Mutate_(op, e);
op = expr.as<Load>();
if (read_access_ && buf_var_ == op->buffer_var.get()) {
return Load::make(
op->dtype, op->buffer_var, ir::Simplify(op->index - min_),
op->predicate);
} else {
return expr;
}
}
Stmt Mutate_(const Store* op, const Stmt& s) final {
Stmt stmt = IRMutator::Mutate_(op, s);
op = stmt.as<Store>();
if (!read_access_ && buf_var_ == op->buffer_var.get()) {
return Store::make(
op->buffer_var, op->value, ir::Simplify(op->index - min_),
op->predicate);
} else {
return stmt;
}
}
private:
// The buffer variable.
const Variable* buf_var_;
// The min bound.
Expr min_;
// read or write
bool read_access_{true};
};
// Rewrite channel access pattern.
class ChannelAccessRewriter : public IRMutator {
public:
Stmt Mutate_(const AttrStmt* op, const Stmt& s) final {
Stmt ret;
const AttrStmt* adv = op->body.as<AttrStmt>();
if ((op->attr_key == ir::attr::channel_read_scope &&
adv && adv->attr_key == ir::attr::channel_read_advance) ||
(op->attr_key == ir::attr::channel_write_scope &&
adv && adv->attr_key == ir::attr::channel_write_advance)) {
RewriteEntry e;
e.window = op;
e.advance = adv;
e.read_access = op->attr_key == ir::attr::channel_read_scope;
tasks_.push_back(e);
ret = IRMutator::Mutate_(op, s);
if (tasks_.back().rewrite_success) {
ret = ret.as<AttrStmt>()->body.as<AttrStmt>()->body;
}
tasks_.pop_back();
return ret;
} else {
return IRMutator::Mutate_(op, s);
}
}
Stmt Mutate_(const For* op, const Stmt& s) final {
std::vector<RewriteEntry> tasks;
std::swap(tasks_, tasks);
Stmt body = op->body;
std::vector<Stmt> nest;
for (RewriteEntry& e : tasks) {
body = RewriteAccess(op, body, &e, &nest);
}
if (!body.same_as(op->body)) {
body = Mutate(body);
body = For::make(
op->loop_var, op->min, op->extent,
op->for_type, op->device_api, body);
body = MergeNest(nest, body);
} else {
CHECK_EQ(nest.size(), 0U);
body = IRMutator::Mutate_(op, s);
}
std::swap(tasks_, tasks);
return body;
}
private:
struct RewriteEntry {
bool read_access;
const AttrStmt* window;
const AttrStmt* advance;
bool rewrite_success{false};
};
Stmt RewriteAccess(const For* for_op,
Stmt body,
RewriteEntry* e,
std::vector<Stmt>* outer_nest) {
const AttrStmt* adv_op = e->advance;
const Expr& window = e->window->value;
bool read_access = e->read_access;
Var var(for_op->loop_var);
Channel ch = Downcast<Channel>(adv_op->node);
ChannelAccessBound acc(ch->handle_var.get(), read_access);
IntSet iset = acc.Eval(for_op->body);
Range r = iset.cover_range(Range::make_by_min_extent(0, window));
r = Range::make_by_min_extent(
ir::Simplify(r->min), ir::Simplify(r->extent));
if (ExprUseVar(r->extent, var)) return body;
Array<Expr> linear_eq = DetectLinearEquation(r->min, {var});
if (linear_eq.size() == 0) return body;
Expr coeff = linear_eq[0];
Expr base = linear_eq[1];
if (!is_zero(base)) return body;
Expr left = ir::Simplify(adv_op->value - coeff * for_op->extent);
if (!analyzer_.CanProve(left >= 0)) return body;
// rewrite access index.
ChannelAccessIndexRewriter rw(
ch->handle_var.get(), var * coeff, read_access);
body = rw.Mutate(body);
if (read_access) {
body = AttrStmt::make(
ch, ir::attr::channel_read_scope, r->extent,
AttrStmt::make(ch, ir::attr::channel_read_advance, coeff,
body));
} else {
body = AttrStmt::make(
ch, ir::attr::channel_write_scope, r->extent,
AttrStmt::make(ch, ir::attr::channel_write_advance, coeff,
body));
}
if (!is_zero(left)) {
Stmt no_op = Evaluate::make(0);
if (read_access) {
outer_nest->emplace_back(
AttrStmt::make(ch, ir::attr::channel_read_advance, left, no_op));
} else {
outer_nest->emplace_back(
AttrStmt::make(ch, ir::attr::channel_write_advance, left, no_op));
}
}
e->rewrite_success = true;
return body;
}
arith::Analyzer analyzer_;
std::vector<RewriteEntry> tasks_;
};
Stmt NarrowChannelAccess(Stmt stmt) {
return ChannelAccessRewriter().Mutate(stmt);
}
} // namespace ir
} // namespace tvm
......@@ -23,7 +23,6 @@
*/
#include <tvm/ir.h>
#include <tvm/lowered_func.h>
#include <tvm/channel.h>
#include <tvm/ir_pass.h>
#include <tvm/ir_mutator.h>
#include <tvm/runtime/module.h>
......@@ -54,13 +53,6 @@ class IRUseDefAnalysis : public IRMutator {
Stmt body = this->Mutate(op->body);
if (value.same_as(op->value) && body.same_as(op->body)) return s;
return AttrStmt::make(op->node, op->attr_key, value, body);
} else if (op->attr_key == attr::channel_write_scope ||
op->attr_key == attr::channel_read_scope) {
Channel ch = Downcast<Channel>(op->node);
if (!use_count_.count(ch->handle_var.get())) {
this->HandleDef(ch->handle_var.get());
}
return IRMutator::Mutate_(op, s);
} else {
return IRMutator::Mutate_(op, s);
}
......
......@@ -149,8 +149,6 @@ bool RuntimeEnabled(const std::string& target) {
f_name = "codegen.build_stackvm";
} else if (target == "rpc") {
f_name = "device_api.rpc";
} else if (target == "vpi" || target == "verilog") {
f_name = "device_api.vpi";
} else if (target == "micro_dev") {
f_name = "device_api.micro_dev";
} else if (target.length() >= 5 && target.substr(0, 5) == "nvptx") {
......
# 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.
import tvm
def lower(s, args):
binds = {}
arg_list = []
for x in args:
assert isinstance(x, tvm.tensor.Tensor)
buf = tvm.decl_buffer(x.shape, dtype=x.dtype, name=x.op.name)
binds[x] = buf
arg_list.append(buf)
s.normalize()
bounds = tvm.schedule.InferBound(s)
stmt = tvm.schedule.ScheduleOps(s, bounds)
stmt = tvm.ir_pass.StorageFlatten(stmt, binds, 64)
stmt = tvm.ir_pass.CanonicalSimplify(stmt)
stmt = tvm.ir_pass.Simplify(stmt)
return stmt
def test_basic_pipeline():
n = tvm.convert(128)
A = tvm.placeholder((n,), name='A')
stages = []
num_stage = 3
B = A
for k in range(num_stage):
stages.append(B)
B = tvm.compute((n,), lambda i: B[i] + k, name="A%s" % k)
s = tvm.create_schedule(B.op)
xo, xi = s[B].split(B.op.axis[0], nparts=1)
s[B].bind(xo, tvm.thread_axis("pipeline"))
xo, xi = s[B].split(xi, factor=4)
for S in stages:
s[S].compute_at(s[B], xo)
stmt = lower(s, [A, B])
stmt = tvm.ir_pass.SplitPipeline(stmt, False)
print(stmt)
stmt = tvm.ir_pass.NarrowChannelAccess(stmt)
print(stmt)
assert(tvm.ir_pass.VerifySSA(stmt))
def test_conv1d():
n = tvm.var('n')
A = tvm.compute((n+2), lambda i: 1, name='A')
def computeB(ii):
i = ii + 1
return A[i-1] + A[i] + A[i+1]
B = tvm.compute(n, computeB, name='B')
s = tvm.create_schedule(B.op)
px, xi = s[B].split(B.op.axis[0], nparts=1)
s[B].bind(px, tvm.thread_axis("pipeline"))
s[A].compute_at(s[B], px)
stmt = lower(s, [B])
stmt = tvm.ir_pass.SplitPipeline(stmt, False)
print(stmt)
stmt = tvm.ir_pass.NarrowChannelAccess(stmt)
print(stmt)
if __name__ == "__main__":
test_basic_pipeline()
test_conv1d()
# 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.
# rules for gtest
.PHONY: iverilog
iverilog: | ${CACHE_PREFIX}/bin/vvp
${CACHE_PREFIX}/bin/vvp:
rm -rf verilog-10.1.tar.gz verilog-10.1
wget ftp://icarus.com/pub/eda/verilog/v10/verilog-10.1.tar.gz
tar xf verilog-10.1.tar.gz
cd verilog-10.1;./configure --prefix=${CACHE_PREFIX}; make install
#!/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.
set -e
set -u
export PYTHONPATH=python
make verilog
python3 -m pytest -v tests/verilog/unittest
python3 -m pytest -v tests/verilog/integration
#!/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.
if [ ${TASK} == "lint" ] || [ ${TASK} == "all_test" ]; then
if [ ! ${TRAVIS_OS_NAME} == "osx" ]; then
./tests/scripts/task_lint.sh || exit -1
fi
fi
cp make/config.mk config.mk
echo "USE_CUDA=0" >> config.mk
echo "USE_RPC=1" >> config.mk
if [ ${TRAVIS_OS_NAME} == "osx" ]; then
echo "USE_OPENCL=1" >> config.mk
echo "USE_METAL=1" >> config.mk
else
# use g++-4.8 for linux
if [ ${CXX} == "g++" ]; then
export CXX=g++-4.8
fi
echo "USE_OPENCL=0" >> config.mk
fi
if [ ${TASK} == "verilog_test" ] || [ ${TASK} == "all_test" ]; then
if [ ! ${TRAVIS_OS_NAME} == "osx" ]; then
make -f tests/scripts/packages.mk iverilog
make all || exit -1
./tests/scripts/task_verilog_test.sh || exit -1
fi
fi
if [ ${TASK} == "cpp_test" ] || [ ${TASK} == "all_test" ]; then
make -f dmlc-core/scripts/packages.mk gtest
./tests/scripts/task_cpp_unittest.sh || exit -1
fi
if [ ${TASK} == "python_test" ] || [ ${TASK} == "all_test" ]; then
make all || exit -1
if [ ${TRAVIS_OS_NAME} == "osx" ]; then
./tests/scripts/task_python_unittest.sh || exit -1
else
pytests3 -v tests/python/unittest || exit -1
fi
fi
#!/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.
if [ ${TASK} == "python_test" ] || [ ${TASK} == "all_test" ]; then
if [ ${TRAVIS_OS_NAME} == "osx" ]; then
brew update
brew install python3
python3 -m pip install --user pytest numpy cython
fi
fi
if [ ${TASK} == "lint" ] || [ ${TASK} == "all_test" ]; then
if [ ! ${TRAVIS_OS_NAME} == "osx" ]; then
pip install --user cpplint 'pylint==1.4.4' 'astroid==1.3.6'
fi
fi
#!/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.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment