Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make test_types.py work for the Metal backend #527

Merged
merged 4 commits into from
Feb 25, 2020
Merged

Conversation

k-ye
Copy link
Member

@k-ye k-ye commented Feb 24, 2020

Related issue id = #504 #396

Hi @archibate

Sorry i changed your tests quite a bit, in order to make it work for the Metal backend as well. The problem with Metal is that it doesn't support 64bit buffers, so we had to separate the tests into 64-bit vs the rest.

I found a nice decorator @pytest.mark.parametrize() (doc) that can somewhat simplify the code.

Also I saw that you got this "variables are expected to be declared before kernel invocation" problem, therefore had to create another wrapper inside each test? IIUC, ti.all_archs(_with) resets the test case here:

ti.init(arch=arch, **kwargs)

So by putting @ti.all_archs at the bottom of the decorator chain, we no longer need to wrap it, because it resets Taichi every time the test case is called. (Unfortunately, this doesn't apply to this PR, as explained below)

At last, I tried something like this:

def _test_foo(x):
  ...

@pytest.mark.parametrize('x', [1, 2, 3])
@ti.all_archs
def test_foo(x):
  _test_foo(x)

But @pytest.mark.parametrize didn't work well with @ti.all_archs this way. So I had to once again, wrap the _test_foo() inside test_foo(), so that @ti.all_archs can correctly apply the decoration:

@pytest.mark.parametrize('x', [1, 2, 3])
def test_foo(x):
  @ti.all_archs
  def run():
    _test_foo(x)
  run()

@k-ye k-ye requested a review from archibate February 24, 2020 07:19
@k-ye k-ye self-assigned this Feb 24, 2020
@archibate
Copy link
Collaborator

Also I saw that you got this "variables are expected to be declared before kernel invocation" problem, therefore had to create another wrapper inside each test? IIUC, ti.all_archs(_with) resets the test case.

Sounds to be a good solution for this!

But @pytest.mark.parametrize didn't work well with @ti.all_archs this way.

So that the problem is, ti.all_archs didn't pass x to test_foo in the first case?

@archibate
Copy link
Collaborator

That's strange, in:

def wrapped(*test_args, **test_kwargs):

test arguments should be recognized...

@k-ye
Copy link
Member Author

k-ye commented Feb 24, 2020

That's strange, in:

def wrapped(*test_args, **test_kwargs):

test arguments should be recognized...

Yeah, I think pytest.mark.parametrize only knows about the normal function arguments, no defaults, no *args, no **kwargs... pytest-dev/pytest#3221 Unfortunately we have to put @ti.all_archs at the bottom of this chain :(

Similar issue: https://stackoverflow.com/questions/12197263/pytest-parameterize-decorator-not-working-with-kwargs

@archibate
Copy link
Collaborator

archibate commented Feb 24, 2020

Maybe we could customize our own parametrize like:

def parametrize(xs):
  def decorator(foo):
    def wrapped(*args, **kwargs):
      for x in xs:
        foo(x, *args, **kwargs)
    return wrapped
  return decorator

@parametrize([1, 2, 3])
@ti.all_archs
def test_func(x):
  assert x == 233

@k-ye
Copy link
Member Author

k-ye commented Feb 24, 2020

Maybe we can customize our own parametrize like

SG! While I generally don't prefer maintaining our own utilities for such things that are not essential to Taichi, I guess having a @ti.parametrize will work better for our tests, because most of them need to use @ti.all_arch. Thanks!

@archibate
Copy link
Collaborator

archibate commented Feb 24, 2020

Cool implementation! I just opened an issue for this, see pytest-dev/pytest#6810.

@archibate
Copy link
Collaborator

archibate commented Feb 24, 2020

Their reply: pytest-dev/pytest#6810 (comment).
They say we can solve this by adding @functools.wraps before this line:

def wrapped(*test_args, **test_kwargs):

How do you think?

@k-ye
Copy link
Member Author

k-ye commented Feb 24, 2020

Thank you so much for following up with the pytest team! Yeah, after decorating the tests with @functools.wraps, we can now integrate with @pytest.mark.parametrize!! Again, really appreciate your efforts! (BTW I'm not available during working hours, so I will have to catch up new comments later tonight..)

Copy link
Member

@yuanming-hu yuanming-hu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thank you @k-ye @archibate!

@k-ye k-ye merged commit 6b03e7a into taichi-dev:master Feb 25, 2020
@k-ye k-ye deleted the t branch February 25, 2020 10:23
yuanming-hu pushed a commit that referenced this pull request Feb 26, 2020
* Use @functools.wrap, thanks to @archibate!
* Initialize LLVM runtime for Metal backend as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants