Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Updating the 'System.Runtime.Extensions' contracts to include the new single-precision Math APIs. #12183

Merged
merged 4 commits into from
Oct 26, 2016

Conversation

tannergooding
Copy link
Member

This updates the System.Runtime.Extensions contracts to include the new single-precision Math APIs approved in #1151 and implemented in CoreCLR in dotnet/coreclr#5492.

@tannergooding
Copy link
Member Author

tannergooding commented Sep 29, 2016

Unit Tests for the System.MathF class still need to be written (I am currently working on porting the existing System.Math tests).

@hughbe
Copy link

hughbe commented Sep 29, 2016

Have these APIs only been approved for .net core?
If so, you'll need to expose these new APIs under netcoreapp1.1, see #12036

@tannergooding
Copy link
Member Author

@terrajobst, could you clarify on which TFMs the new APIs have been approved for?

@karelz
Copy link
Member

karelz commented Oct 10, 2016

Yes, these APIs were approved for .NET Core in #1151.
@mellinoe can provide additional guidance/help if needed.

@mellinoe
Copy link
Contributor

We can only add this to netcoreapp, so you'll need to follow other recent PR's that have done that, and/or refer to the document @weshaggard is working on above.

@tannergooding
Copy link
Member Author

tannergooding commented Oct 10, 2016

@mellinoe, the document above is somewhat confusing, as it says any change that is not part of netstandard but that depends directly on a runtime change, then the target framework should be netstandard<latest>.

It seems like these changes have an actual dependency on the Microsoft.TargetingPack.Private.CoreCLR, based on the their being an actual runtime dependency with FCALLs being added.

Is this not the case?

@mellinoe
Copy link
Contributor

@weshaggard Could you clarify that point a bit? These are new API's for .NET Core, which rely on new FCALL's.

@weshaggard
Copy link
Member

Thanks for the feedback on the documentation. I will try and incorporate and update once I can get back to that. As @mellinoe points out though these are definitely in the bucket of netstandard APIs they just aren't part of any standard yet and as such they need to be added as .NET Core specific for now.

In the mean time I suggest using #12226 as an example for how to add APIs to .NET Core specifically.

@karelz
Copy link
Member

karelz commented Oct 15, 2016

@tannergooding was the info from @weshaggard helpful? Anything else we can help with here?

@tannergooding
Copy link
Member Author

@karelz, yes it was. I have just had my focus elsewhere due to the current schedule. I am going to take some time today to fix up this and the other PR.

@tannergooding
Copy link
Member Author

Pretty sure I've updated these all appropriately now.

System.MathF tests are still blocked on getting the CoreCLR side merged so that we can get a Microsoft.TargetingPack.Private.CoreCLR package with the required changes.

@tannergooding
Copy link
Member Author

@mellinoe, the CoreCLR side changes have been merged.

About how long does it take before a Microsoft.TargetingPack.Private.CoreCLR is available for me to update everything to (and is there an automated/documented process for moving that forward)?

@tannergooding
Copy link
Member Author

Actually, it looks like @dotnet-bot does automated PRs at least once a day. I suppose I will need to wait for the next one (after the current one is merged) to complete.

@tannergooding
Copy link
Member Author

Looks like it will be one more PR. The one that just came up (#12756) is a commit before my changes 😄

@tannergooding
Copy link
Member Author

Rebased onto HEAD. Going to start writing the System.MathF tests now that the contract assembly is available.

@tannergooding
Copy link
Member Author

I've ported the existing System.Math unit tests for the new System.MathF APIs.

The coverage that exists for System.Math is surprisingly small. I think I'm going to open an issue for expanding it in a separate PR. I would think, at the very least, we could replicate the test coverage we have over the native implementations in the PAL layer (this correlates to roughly 20 tests per API, at a minimum, and ensures we cover the interesting values as well).

@mellinoe
Copy link
Contributor

As a general note, it would be nice to get the test cases factored out into [Theory]s. Better logging and better separation of individual issues, if they occur.

Copy link
Contributor

@mellinoe mellinoe left a comment

Choose a reason for hiding this comment

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

Changes look good overall; I made a few small comments on the tests. Thanks for all of the work you've done on this, I'm looking forward to using it when we get it through 😄

[Fact]
public static void Abs()
{
AssertEqual(MathF.PI, MathF.Abs(MathF.PI));
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see this two-parameter AssertEquals method anywhere. Am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was a mistake on my side, the calls that do not have an expected precision (and should be exact values) should still call Assert.Equal.

// This is essentially equivalent to the Xunit.Assert.Equal(double, double, int) implementation
// available here: https://github.com/xunit/xunit/blob/2.1/src/xunit.assert/Asserts/EqualityAsserts.cs#L46

var expectedRounded = MathF.Round(expected, precision);
Copy link
Contributor

Choose a reason for hiding this comment

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

The use of a MathF function here raises a flag for me, since this is a core assertion used by the rest of the tests. It would be nice if the MathF.Round tests didn't use this, at the very least.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the exact behavior that the double tests currently use. But I agree, it is undesirable.

I am going to go ahead and convert this to use the same logic as the PAL tests I wrote, which is:

var delta = MathF.Abs(result - expected);
if (delta > allowedVariance)
{
    throw new EqualException(...);
}

Where allowedVariance is the cross platform machine epsilon (4.76837158e-07f) multiplied by the a power of 10 to allow for proper rounding (so an expected result of 0.xxxxxxxxx is just machine epsilon, while x.xxxxxxxx is machine epsilon * 10, and 0.0xxxxxxxxx is machine epsilon / 10).

This is at least better in the sense that MathF.Abs calls to the existing Math.Abs function, which is known to be good.

@tannergooding
Copy link
Member Author

@mellinoe, I agree that converting these to use [Theory] is desirable. I will log that as part of the bug (mentioned above) to expand the test coverage here and in System.Math.

I am going to assign the bug to myself and start on it immediately, but would like to get the initial change completed since it provides parity with the System.Math coverage and will allow me to finish writing the performance tests for the CoreCLR repo.

@mellinoe
Copy link
Contributor

but would like to get the initial change completed since it provides parity with the System.Math coverage and will allow me to finish writing the performance tests for the CoreCLR repo

Sounds good to me.

@tannergooding
Copy link
Member Author

FYI. @mellinoe the bug tracking the additional test work is here: https://github.com/dotnet/corefx/issues/12855

@tannergooding
Copy link
Member Author

The contracts for System.MathF were slightly messed up when the NGEN aliasing issue was fixed. #12836 contains the necessary fixes (beta-24620-03+)

@tannergooding
Copy link
Member Author

@mellinoe, I must be missing some change that causes System.Runtime.Extensions to attempt to load System.MathF from the Microsoft.TargetingPack.Private.CoreCLR package rather than from System.Runtime.Extensions itself...

Are you aware of what is missing here?

@tannergooding
Copy link
Member Author

Looks like what I'm missing is whatever causes the TypeForwardedTo declarations to appear in Sytem.Runtime.Extensions. However, these appear to be automatically generated by something (and it isn't obvious to me from going through the project and targets files).

@tannergooding
Copy link
Member Author

Ok, after a lot more digging, it looks like the project ends up running GenFacades post build. It also looks like this ends up using bin\ref\System.Runtime.Extensions\4.2.0.0\System.Runtime.Extensions.dll as the contracts assembly, rather than bin\ref\System.Runtime.Extensions\4.2.0.0\netcoreapp1.1\System.Runtime.Extensions.dll, so it doesn't end up creating the redirects for System.MathF.

@tannergooding
Copy link
Member Author

I can 'fix' the issue and get tests passing by adding a new source file and manually adding the appropriate type forward. However, I do not believe this is the correct fix.

Could someone please confirm what the correct fix is here?

@tannergooding
Copy link
Member Author

Ping @mellinoe to answer (or direct to someone for answering) the above question.

@mellinoe
Copy link
Contributor

@tannergooding Sorry about not getting back to you. I'll take a look at your branch and see if I can figure out the problem.

@tannergooding
Copy link
Member Author

Thanks!

@mellinoe
Copy link
Contributor

@tannergooding It looks like there is a limitation in how we are resolving the contract references right now: dotnet/buildtools#1041. We're in a sort of intermediate state right now where we have two different build configurations for the reference assembly, and the one we're choosing right now is not correct for this scenario, as you discovered. Eventually the problem will go away because we will only have one reference assembly, but that is still in the works.

Right now, just go ahead and add the manual type-forward file like you mentioned above. If you don't mind, please put a comment in the csproj file (or in the .cs file) mentioning dotnet/buildtools#1041 so that we remember to revert it when that is fixed.

@tannergooding
Copy link
Member Author

@mellinoe, Thanks for the confirmation. I have added the manual TypeForwardedToAttribute for System.MathF and ensured that both the .cs file and the .csproj file have a link to the bug.

Slightly separate here, but I noticed the following in the .csproj file (https://github.com/dotnet/corefx/blob/master/src/System.Runtime.Extensions/src/System.Runtime.Extensions.csproj#L382)

<ItemGroup Condition="'$(TargetGroup)' == 'net462' Or '$(TargetGroup)' == 'net463'">
  <TargetingPackReference Include="mscorlib" />
  <TargetingPackReference Include="System" />
</ItemGroup>
<ItemGroup Condition="'$(TargetGroup)' != 'net462' Or '$(TargetGroup)' != 'net463'">
  <TargetingPackReference Include="System.Private.CoreLib" />
</ItemGroup>

Specifically, the condition on the second ItemGroup is using Or, when I would have expected it to use And (as is the case in several other .csproj files I checked).

Is this by-design, or can I include a fix for it here?

@tannergooding
Copy link
Member Author

@mellinoe, everything is looking good here.

@mellinoe
Copy link
Contributor

Specifically, the condition on the second ItemGroup is using Or, when I would have expected it to use And (as is the case in several other .csproj files I checked).
Is this by-design, or can I include a fix for it here?

This is probably harmless since nothing seems to be breaking in those configurations. Strictly speaking we should probably fix it, but I was chatting with @ericstj and we thought that we really should only have one of these net46 configurations in the first place. So if we wanted to fix it, we would probably just delete one of those configurations and the problem would go away. I would say just ignore it for this work here.

@mellinoe
Copy link
Contributor

Everything looks good to me. Thanks a lot for all the work you've put into this. It looks like a really high-quality addition, and I know I'm planning on using it in some of my projects.

@mellinoe mellinoe merged commit ec87e62 into dotnet:master Oct 26, 2016
@tannergooding
Copy link
Member Author

Thanks! I will continue working on getting the remaining work (perf tests, expanded unit tests, etc) done in my spare time!

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

Successfully merging this pull request may close these issues.

6 participants