Skip to content
This repository has been archived by the owner on Aug 15, 2019. It is now read-only.

Packed reverse #1617

Merged
merged 8 commits into from
Mar 18, 2019
Merged

Packed reverse #1617

merged 8 commits into from
Mar 18, 2019

Conversation

jgartman
Copy link
Contributor

@jgartman jgartman commented Mar 10, 2019

Adds a packed kernel for reverse:

shape Packed (ms) Unpacked (ms)
[100, 100] 5.814 5.542
[200, 200] 6.002 5.640
[500, 500] 7.109 16.257
[1000, 1000] 18.289 44.871

Benchmark code:

export class ReverseGPUBenchmark implements BenchmarkTest {
  async run(size: number): Promise<number> {
    tf.setBackend('webgl');
    tf.ENV.set('WEBGL_PACK', false);
    const t: tf.Tensor<tf.Rank.R2> = tf.randomNormal([size, size]);

    const benchmark = () => tf.reverse(t, [0]) as tf.Tensor;

    const time = await util.warmupAndBenchmarkGPU(benchmark);

    t.dispose();

    return time;
  }
}

Compiled shader code for reverse of tensor of shape = [2, 3, 4] along axis = 1:

     void main() {
          ivec3 rc = getOutputCoords();
          vec4 result = vec4(0.);
          result.r = getChannel(getX(rc.x,3 - rc.y - 1,rc.z), vec2(3 - rc.y - 1,rc.z));
          if(rc.z + 1 < 4){
            result.g = getChannel(getX(rc.x,3 - rc.y - 1,(rc.z + 1)), vec2(3 - rc.y - 1,(rc.z + 1)));
          }
          if(rc.y + 1 < 3) {
            result.b = getChannel(getX(rc.x,3 - (rc.y + 1) - 1,rc.z), vec2(3 - (rc.y + 1) - 1,rc.z));
            if(rc.z + 1 < 4) {
              result.a = getChannel(getX(rc.x,3 - (rc.y + 1) - 1,(rc.z + 1)), vec2(3 - (rc.y + 1) - 1,(rc.z + 1)));
            }
          }
          setOutput(result);
        }
      

This change is Reviewable

Copy link
Collaborator

@annxingyuan annxingyuan left a comment

Choose a reason for hiding this comment

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

Hey @jgartman - thank you so much for this! I left some mostly stylistic suggestions - otherwise this is good to go.

Could you also add a test for reverse on an array with odd number of rows and columns (final two dimensions)?

Thanks - we'll merge this soon!


this.userCode = `
void main() {
${type} rc = getOutputCoords();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Indent these lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -0,0 +1,80 @@
/**
* @license
* Copyright 2019 Google Inc. All Rights Reserved.
Copy link
Collaborator

Choose a reason for hiding this comment

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

LLC.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

this.outputShape = xShape;
const channels = getChannels('rc', rank);
const nextColumn =
`++${channels[rank - 1]} < ${this.outputShape[rank - 1]}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I realize that we have this pattern elsewhere in the packed shaders, but could we instead test for adding 1 to the coordinate rather than mutating the coordinate? That way we don't have to remember to clean up after ourselves and decrement the coordinate. I think it'll be a little bit easier to read as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @annxingyuan, I refactored the code a bit and updated the compiled shader code at the top of the PR as well. Let me know what you think.

const type = getCoordsDataType(rank);
const getc = `getChannel(getX(${inCoords}), ${innerDims})`;

const upperRow = `
Copy link
Collaborator

Choose a reason for hiding this comment

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

What do you think about restructuring this shader to match the unpacked shader so that all the logic for rank = 1 is nested under one if-statement? I wonder whether it might be easier to read that way - avoids having to test for rank = 1 in so many places. If we did it this way we should also be able to inline upperRow and lowerRow in the body of void main below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@annxingyuan annxingyuan merged commit 778f62a into tensorflow:master Mar 18, 2019
@annxingyuan
Copy link
Collaborator

Thanks @jgartman !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants