Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
lin-hitonami committed Mar 8, 2022
2 parents a5a75d7 + f714872 commit efd064b
Show file tree
Hide file tree
Showing 60 changed files with 778 additions and 546 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ jobs:
run: |
if [ -z "${{ github.event.action }}" ]; then
# For nightly release, we only run on python 3.8
echo '::set-output name=matrix::{"include":[{"name":"taichi-nightly","python":"3.8","conda_python":"py38"}]}"'
echo '::set-output name=matrix::{"include":[{"name":"taichi-nightly","python":"3.8","conda_python":"py38"},{"name":"taichi-nightly","python":"3.10","conda_python":"py310"}]}"'
# M1 only supports py38 and py39(conda), so change matrix.
echo '::set-output name=matrix_osx::{"include":[{"name":"taichi-nightly","python":"3.8"}]}"'
echo '::set-output name=matrix_osx::{"include":[{"name":"taichi-nightly","python":"3.8"},{"name":"taichi-nightly","python":"3.10"}]}"'
else
# For production release, we run on four python versions.
echo '::set-output name=matrix::{"include":[{"name":"taichi","python":"3.6","conda_python":"py36"},{"name":"taichi","python":"3.7","conda_python":"py37"},{"name":"taichi","python":"3.8","conda_python":"py38"},{"name":"taichi","python":"3.9","conda_python":"py39"}]}"'
Expand Down
4 changes: 2 additions & 2 deletions docs/lang/articles/advanced/sparse_matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ n = 4
K = ti.linalg.SparseMatrixBuilder(n, n, max_num_triplets=100)

@ti.kernel
def fill(A: ti.linalg.sparse_matrix_builder()):
def fill(A: ti.types.sparse_matrix_builder()):
for i in range(n):
A[i, i] += 1 # Only += and -= operators are supported for now.

Expand Down Expand Up @@ -146,7 +146,7 @@ K = ti.linalg.SparseMatrixBuilder(n, n, max_num_triplets=100)
b = ti.field(ti.f32, shape=n)

@ti.kernel
def fill(A: ti.linalg.sparse_matrix_builder(), b: ti.template(), interval: ti.i32):
def fill(A: ti.types.sparse_matrix_builder(), b: ti.template(), interval: ti.i32):
for i in range(n):
A[i, i] += 2.0

Expand Down
2 changes: 1 addition & 1 deletion misc/spMv_linear_solve.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


@ti.kernel
def fill(A: ti.linalg.sparse_matrix_builder(), b: ti.template(),
def fill(A: ti.types.sparse_matrix_builder(), b: ti.template(),
interval: ti.i32):
for i in range(n):
A[i, i] += 2.0
Expand Down
4 changes: 2 additions & 2 deletions misc/sparse_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@


@ti.kernel
def fill(A: ti.linalg.sparse_matrix_builder(),
b: ti.linalg.sparse_matrix_builder(), interval: ti.i32):
def fill(A: ti.types.sparse_matrix_builder(),
b: ti.types.sparse_matrix_builder(), interval: ti.i32):
for i in range(n):
if i > 0:
A[i - 1, i] += -1.0
Expand Down
2 changes: 1 addition & 1 deletion python/taichi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Provide a shortcut to types since they're commonly used.
from taichi.types.primitive_types import *

from taichi import ad, linalg, tools
from taichi import ad, experimental, linalg, tools
from taichi.ui import GUI, hex_to_rgb, rgb_to_hex, ui

# Issue#2223: Do not reorder, or we're busted with partially initialized module
Expand Down
64 changes: 36 additions & 28 deletions python/taichi/_version_check.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import datetime
import json
import os
import platform
import threading
import uuid
from urllib import request

from taichi._lib import core as _ti_core

def check_version():

def check_version(cur_uuid):
# Check Taichi version for the user.
major = _ti_core.get_version_major()
minor = _ti_core.get_version_minor()
Expand Down Expand Up @@ -35,7 +39,10 @@ def check_version():
payload['python'] = 'cp38'
elif python_version.startswith('3.9.'):
payload['python'] = 'cp39'
elif python_version.startswith('3.10.'):
payload['python'] = 'cp310'

payload['uuid'] = cur_uuid
# We do not want request exceptions break users' usage of Taichi.
try:
payload = json.dumps(payload)
Expand All @@ -50,39 +57,40 @@ def check_version():
return None


def write_version_info(response, cur_uuid, version_info_path, cur_date):
if response is None:
return
with open(version_info_path, 'w') as f:
f.write((cur_date).strftime('%Y-%m-%d'))
f.write('\n')
if response['status'] == 1:
f.write(response['latest_version'])
else:
f.write('0.0.0')
f.write('\n')
f.write(cur_uuid)
f.write('\n')


def try_check_version():
try:
os.makedirs(_ti_core.get_repo_dir(), exist_ok=True)
timestamp_path = os.path.join(_ti_core.get_repo_dir(), 'timestamp')
version_info_path = os.path.join(_ti_core.get_repo_dir(),
'version_info')
cur_date = datetime.date.today()
if os.path.exists(timestamp_path):
last_time = ''
with open(timestamp_path, 'r') as f:
last_time = f.readlines()[0].rstrip()
if os.path.exists(version_info_path):
with open(version_info_path, 'r') as f:
version_info_file = f.readlines()
last_time = version_info_file[0].rstrip()
cur_uuid = version_info_file[2].rstrip()
if cur_date.strftime('%Y-%m-%d') > last_time:
response = check_version()
if response is None:
return
with open(timestamp_path, 'w') as f:
f.write((cur_date +
datetime.timedelta(days=7)).strftime('%Y-%m-%d'))
f.write('\n')
if response['status'] == 1:
f.write(response['latest_version'])
else:
f.write('0.0.0')
response = check_version(cur_uuid)
write_version_info(response, cur_uuid, version_info_path,
cur_date)
else:
response = check_version()
if response is None:
return
with open(timestamp_path, 'w') as f:
f.write((cur_date +
datetime.timedelta(days=7)).strftime('%Y-%m-%d'))
f.write('\n')
if response['status'] == 1:
f.write(response['latest_version'])
else:
f.write('0.0.0')
cur_uuid = str(uuid.uuid4())
response = check_version(cur_uuid)
write_version_info(response, cur_uuid, version_info_path, cur_date)
# Wildcard exception to catch potential file writing errors.
except:
pass
Expand Down
6 changes: 3 additions & 3 deletions python/taichi/examples/simulation/implicit_mass_spring.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def init_edges(self):
rest_len[idx] = (pos[idx1] - pos[idx2]).norm()

@ti.kernel
def init_mass_sp(self, M: ti.linalg.sparse_matrix_builder()):
def init_mass_sp(self, M: ti.types.sparse_matrix_builder()):
for i in range(self.NV):
mass = self.mass[i]
M[2 * i + 0, 2 * i + 0] += mass
Expand Down Expand Up @@ -137,7 +137,7 @@ def compute_Jacobians(self):
self.Jf[1] = ti.Matrix([[-self.kf, 0], [0, -self.kf]])

@ti.kernel
def assemble_K(self, K: ti.linalg.sparse_matrix_builder()):
def assemble_K(self, K: ti.types.sparse_matrix_builder()):
for i in self.spring:
idx1, idx2 = self.spring[i][0], self.spring[i][1]
for m, n in ti.static(ti.ndrange(2, 2)):
Expand All @@ -150,7 +150,7 @@ def assemble_K(self, K: ti.linalg.sparse_matrix_builder()):
K[2 * (self.NV - 1) + m, 2 * (self.NV - 1) + n] += self.Jf[1][m, n]

@ti.kernel
def assemble_D(self, D: ti.linalg.sparse_matrix_builder()):
def assemble_D(self, D: ti.types.sparse_matrix_builder()):
for i in self.spring:
idx1, idx2 = self.spring[i][0], self.spring[i][1]
for m, n in ti.static(ti.ndrange(2, 2)):
Expand Down
2 changes: 1 addition & 1 deletion python/taichi/examples/simulation/stable_fluid.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def swap(self):
if use_sparse_matrix:
# use a sparse matrix to solve Poisson's pressure equation.
@ti.kernel
def fill_laplacian_matrix(A: ti.linalg.sparse_matrix_builder()):
def fill_laplacian_matrix(A: ti.types.sparse_matrix_builder()):
for i, j in ti.ndrange(res, res):
row = i * res + j
center = 0.0
Expand Down
3 changes: 3 additions & 0 deletions python/taichi/experimental.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from taichi.lang.kernel_impl import real_func

__all__ = ["real_func"]
20 changes: 10 additions & 10 deletions python/taichi/lang/ast/ast_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,10 @@ def transform_as_kernel():
ctx.create_variable(arg.arg, ctx.global_vars[arg.arg])
elif isinstance(ctx.func.argument_annotations[i],
annotations.sparse_matrix_builder):
ctx.create_variable(arg.arg,
kernel_arguments.decl_sparse_matrix())
ctx.create_variable(
arg.arg,
kernel_arguments.decl_sparse_matrix(
to_taichi_type(ctx.arg_features[i])))
elif isinstance(ctx.func.argument_annotations[i],
annotations.any_arr):
ctx.create_variable(
Expand All @@ -482,7 +484,7 @@ def transform_as_kernel():
transform_as_kernel()

else: # ti.func
if impl.get_runtime().experimental_real_function:
if ctx.is_real_function:
transform_as_kernel()
else:
len_args = len(args.args)
Expand Down Expand Up @@ -524,12 +526,12 @@ def transform_as_kernel():

@staticmethod
def build_Return(ctx, node):
if not impl.get_runtime().experimental_real_function:
if not ctx.is_real_function:
if ctx.is_in_non_static_control_flow():
raise TaichiSyntaxError(
"Return inside non-static if/for is not supported")
build_stmt(ctx, node.value)
if ctx.is_kernel or impl.get_runtime().experimental_real_function:
if ctx.is_kernel or ctx.is_real_function:
# TODO: check if it's at the end of a kernel, throw TaichiSyntaxError if not
if node.value is not None:
if ctx.func.return_type is None:
Expand Down Expand Up @@ -557,7 +559,7 @@ def build_Return(ctx, node):
# only need to replace the object part, i.e. args[0].value
else:
ctx.return_data = node.value.ptr
if not impl.get_runtime().experimental_real_function:
if not ctx.is_real_function:
ctx.returned = True
return None

Expand Down Expand Up @@ -1109,13 +1111,11 @@ def build_If(ctx, node):
@staticmethod
def build_Expr(ctx, node):
build_stmt(ctx, node.value)
if not isinstance(
node.value,
ast.Call) or not impl.get_runtime().experimental_real_function:
if not isinstance(node.value, ast.Call):
return None
is_taichi_function = getattr(node.value.func.ptr,
'_is_taichi_function', False)
if is_taichi_function:
if is_taichi_function and node.value.func.ptr._is_real_function:
func_call_result = node.value.ptr
ctx.ast_builder.insert_expr_stmt(func_call_result.ptr)
return None
Expand Down
4 changes: 3 additions & 1 deletion python/taichi/lang/ast/ast_transformer_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ def __init__(self,
file=None,
src=None,
start_lineno=None,
ast_builder=None):
ast_builder=None,
is_real_function=False):
self.func = func
self.local_scopes = []
self.loop_scopes = []
Expand All @@ -140,6 +141,7 @@ def __init__(self,
self.returned = False
self.ast_builder = ast_builder
self.visited_funcdef = False
self.is_real_function = is_real_function

# e.g.: FunctionDef, Module, Global
def variable_scope_guard(self):
Expand Down
49 changes: 47 additions & 2 deletions python/taichi/lang/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from taichi.lang import impl
from taichi.lang.common_ops import TaichiOperations
from taichi.lang.exception import TaichiTypeError
from taichi.lang.util import is_taichi_class
from taichi.lang.util import is_taichi_class, to_numpy_type, to_taichi_type
from taichi.types.primitive_types import integer_types, real_types


# Scalar, basic data type
Expand All @@ -30,7 +31,7 @@ def __init__(self, *args, tb=None, dtype=None):
"Only 0-dimensional numpy array can be used to initialize a scalar expression"
)
arg = arg.dtype.type(arg)
self.ptr = impl.make_constant_expr(arg, dtype).ptr
self.ptr = make_constant_expr(arg, dtype).ptr
else:
assert False
if self.tb:
Expand All @@ -47,6 +48,50 @@ def __repr__(self):
return '<ti.Expr>'


def _check_in_range(npty, val):
iif = np.iinfo(npty)
if not iif.min <= val <= iif.max:
# This isn't the case we want to deal with: |val| does't fall into the valid range of either
# the signed or the unsigned type.
raise TaichiTypeError(
f'Constant {val} has exceeded the range of {to_taichi_type(npty)}: [{iif.min}, {iif.max}]'
)


def _clamp_unsigned_to_range(npty, val):
# npty: np.int32 or np.int64
iif = np.iinfo(npty)
if iif.min <= val <= iif.max:
return val
cap = (1 << iif.bits)
assert 0 <= val < cap
new_val = val - cap
return new_val


def make_constant_expr(val, dtype):
if isinstance(val, (int, np.integer)):
constant_dtype = impl.get_runtime(
).default_ip if dtype is None else dtype
if constant_dtype not in integer_types:
raise TaichiTypeError(
'Integer literals must be annotated with a integer type. For type casting, use `ti.cast`.'
)
_check_in_range(to_numpy_type(constant_dtype), val)
return Expr(
_ti_core.make_const_expr_int(
constant_dtype, _clamp_unsigned_to_range(np.int64, val)))
if isinstance(val, (float, np.floating)):
constant_dtype = impl.get_runtime(
).default_fp if dtype is None else dtype
if constant_dtype not in real_types:
raise TaichiTypeError(
'Floating-point literals must be annotated with a floating-point type. For type casting, use `ti.cast`.'
)
return Expr(_ti_core.make_const_expr_fp(constant_dtype, val))
raise TaichiTypeError(f'Invalid constant scalar data type: {type(val)}')


def make_var_list(size):
exprs = []
for _ in range(size):
Expand Down
Loading

0 comments on commit efd064b

Please sign in to comment.