Skip to content

feature/sym: shape checking tooling for DiffSharp#207

Closed
dsyme wants to merge 19 commits intofeature/gmodelsfrom
feature/sym
Closed

feature/sym: shape checking tooling for DiffSharp#207
dsyme wants to merge 19 commits intofeature/gmodelsfrom
feature/sym

Conversation

@dsyme
Copy link
Copy Markdown
Collaborator

@dsyme dsyme commented Oct 5, 2020

Foundations for shape checking and inference, discussed with @gbaydin today

see #274 for more details

Quick guide to the design and implementation

DiffSharp.Core:

  • Shapes are potentially symbolic Int[]. Here Int is a potentially symbolic integer. The cost is one extra word on the Int struct and one extra word on the Shape struct, there are implementations of no-cost non-symbolic Int and Shape under NO_SYMBOLIC_SHAPE define in the codebase if we ever need to trim this back.

  • For a core operator, constraints are generated during tensor execution (eg with ShapeChecking backend) via a Shape.checkXYZ call which is implemented as a series of checks which generate constraints, see also here and here

  • These constraints are not processed directly by DiffSharp.Core but are rather emitted via a sink ISymScope attached to any symbolic shapes encountered. If no symbolic shapes are present (as in normal tensor execution) then no ISymScope is needed.

  • Internally in Tensor.fs and RawTensor.fs the Shape type is used (e.g. member internal tensor.conv2dx). In the default public API you get via open DiffSharp, i.e. Tensor and dsharp.*, shapes are int[]. There is essentially no change to the external API.

  • Parts of the external API are replicated and adjusted with potentially-symbolic shapes in open DiffSharp.ShapeChecking. Users can use this if they want the option of full symbolic shape checking, e.g. w.r.t. symbolic stride, padding, dialation, tensor indexing and so on. The use this API is not always necessary though - you can shape check with non-symbolic shapes without this, and even some symbolic shapes e.g. on inputs.

tools/DiffSharp.ShapeChecking:

The end result is that the shape checking tooling runs your code as you type in a special "live check, shape check" mode using a restricted form of execution, with attention to generate good hover tips and diagnostics

@dsyme dsyme mentioned this pull request Oct 6, 2020
@codecov
Copy link
Copy Markdown

codecov bot commented Oct 6, 2020

Codecov Report

Merging #207 (faf98ab) into feature/gmodels (a9f9182) will decrease coverage by 5.93%.
The diff coverage is 30.83%.

❗ Current head faf98ab differs from pull request most recent head 1920c8e. Consider uploading reports for the commit 1920c8e to get more accurate results
Impacted file tree graph

@@                 Coverage Diff                 @@
##           feature/gmodels     #207      +/-   ##
===================================================
- Coverage            65.26%   59.33%   -5.93%     
===================================================
  Files                   29       28       -1     
  Lines                 6664     7350     +686     
  Branches              1573     1669      +96     
===================================================
+ Hits                  4349     4361      +12     
- Misses                1472     2147     +675     
+ Partials               843      842       -1     
Impacted Files Coverage Δ
src/DiffSharp.Core/Device.fs 23.81% <0.00%> (-1.19%) ⬇️
src/DiffSharp.Core/Tensor.fs 61.86% <ø> (-1.11%) ⬇️
src/DiffSharp.Data/Plot.fs 0.00% <0.00%> (ø)
src/DiffSharp.Core/Symbols.fs 2.60% <2.60%> (ø)
....Backends.ShapeChecking/ShapeChecking.RawTensor.fs 6.10% <6.10%> (ø)
src/DiffSharp.Core/DiffSharp.ShapeChecking.fs 16.48% <16.48%> (ø)
...rp.Backends.ShapeChecking/ShapeChecking.Symbols.fs 19.21% <19.21%> (ø)
src/DiffSharp.Core/IntType.fs 25.00% <25.00%> (ø)
src/DiffSharp.Core/ShapeType.fs 44.29% <44.29%> (ø)
src/DiffSharp.Core/ShapeFunctions.fs 56.65% <45.23%> (ø)
... and 39 more

@dsyme
Copy link
Copy Markdown
Collaborator Author

dsyme commented Oct 7, 2020

Some sample symbolic shape inference, for example the Conv2DTranspose model:

Model.AnalyseShapes<ConvTranspose3d>(optionals=false)

gives

DiffSharp.Model.Conv3d(C,outChannels)
   Conv3d__bias : [outChannels]
   Conv3d__weight : [outChannels,C,1,1,1]
   forward([N,C,D,H,W]) : [N,outChannels,D,H,W]

This is correctly inferring that the D,H,W of the output is the same as the input, and the C of the model must match the C of the input, and verifies that the outChannels of the model is the outChannels of the input. All very nice.

In the above the kernelSize is an optional parameter and is actually 1. If we want to include optional kernelSize, strides and paddings:

Model.AnalyseShapes<ConvTranspose2d>(optionals=true)

gives:

DiffSharp.Model.ConvTranspose2d(C,outChannels,kernelSize,stride,padding)
   ConvTranspose2d__bias : [outChannels]
   ConvTranspose2d__weight : [C,outChannels,kernelSize,kernelSize]
   forward([N,C,H,W]) : [N,outChannels,stride*(H-1)+kernelSize-2*padding,stride*(W-1)+kernelSize-2*padding]

Note that the full (and quite complicated) shape type of the model's forward function has been inferred automatically from the implementation (by running the symbolic ShapeChecking backend, collecting constraints and solving with Z3).

(In the above hint is actually needed for the names N,C,H,W though that should really be reported by the model I think. )

@dsyme
Copy link
Copy Markdown
Collaborator Author

dsyme commented Oct 10, 2020

Live shape checking tooling - concrete or symbolic - working on DiffSharp models. After discussion with @gbaydin this is with almost no adjustment to the model code, just

  • add [<LiveCheck>] attribute to the model
  • add [<LiveCheck>] attribute to the model entry points you want to test such as loss and forward
  • use Int and Shape in the coding of the model

image

Modified VS tooling and fslive.exe needed as described at the top of this PR

Will make more samples and documentation in due course. But this thing actually works, it's quite amazing.

@dsyme dsyme changed the title [WIP] Feature/sym Shape checking tooling for DiffSharp Oct 15, 2020
@dsyme dsyme changed the base branch from dev to feature/avgpool November 27, 2020 18:21
@dsyme dsyme changed the base branch from feature/avgpool to dev November 28, 2020 15:31
@dsyme dsyme closed this Nov 28, 2020
@dsyme dsyme reopened this Nov 28, 2020
@dsyme dsyme changed the title Shape checking tooling for DiffSharp feature/sym: shape checking tooling for DiffSharp Nov 28, 2020
@dsyme dsyme changed the base branch from dev to feature/gmodels March 4, 2021 14:49
@dsyme dsyme closed this Mar 11, 2021
@dsyme dsyme reopened this Mar 11, 2021
@dsyme dsyme force-pushed the feature/sym branch 2 times, most recently from f96f999 to a5d2213 Compare March 11, 2021 16:13
@dsyme dsyme closed this Mar 10, 2023
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.

1 participant