- Example Visual Studio For Mac Building Backend Api Project Management
- Visual Studio
- Example Visual Studio For Mac Building Backend Api Project Fitness
For us to build our iOS project, we will need to connect your Visual Studio iOS project to a Mac. To do this for the first time, all you do is attempt to build the project. Right-click on the project and select Build. Got a Xamarin solution which includes a project for a web app backend. Trying to set up a separate build definition for the web app backend so that it deploys to Azure app service.
This week’s blog post is by Brian Lui, one of our summer interns on the .NET team, who’s been hard at work. Over to Brian:
Visual Studio code is a light weight source code editor developed by Microsoft, which supports multi OS platform like Windows, Linux and iOS. This editor is helpful in coding and debugging. It also includes intelligent code completion, snippets, code refactoring, embedded Git control and syntax highlighting. Jul 22, 2015 Xamarin Developer Evangelist James Montemagno shows you how the Xamarin Platform enables developers to leverage their C# and.NET skills to create native mobile apps for iOS, Android, Mac. Instead you need to use Project Linker extension for Visual Studio which will ensure you have the same code in your Android project. Refer Visual Studio Project Setup Walkthrough Create an Android Project in the same solution and link the Core project using Project linker.
Hello everyone! This summer I interned in the .NET team, working on ML.NET, an open-source machine learning platform which enables .NET developers to build and use machine learning models in their .NET applications. The ML.NET 0.6 release just shipped and you can try it out today.
At the start of my internship, ML.NET code was already relying on vectorization for performance, using a native code library. This was an opportunity to reimplement an existing codebase in managed code, using .NET Hardware Intrinsics for vectorization, and compare results.
What is vectorization, and what are SIMD, SSE, and AVX?
Vectorization is a name used for applying the same operation to multiple elements of an array simultaneously. On the x86/x64 platform, vectorization can be achieved by using Single Instruction Multiple Data (SIMD) CPU instructions to operate on array-like objects.
SSE (Streaming SIMD Extensions) and AVX (Advanced Vector Extensions) are the names for SIMD instruction set extensions to the x86 architecture. SSE has been available for a long time: the CoreCLR underlying .NET Core requires x86 platforms support at least the SSE2 instruction set. AVX is an extension to SSE that is now broadly available. Its key advantage is that it can handle 8 consecutive 32-bit elements in memory in one instruction, twice as much as SSE can.
.NET Core 3.0 will expose SIMD instructions as API’s that are available to managed code directly, making it unnecessary to use native code to access them.
ARM based CPU’s do offer a similar range of intrinsics but they are not yet supported on .NET Core (although work is in progress). Therefore, it is necessary to use software fallback code paths for the case when neither AVX nor SSE are available. The JIT makes it possible to do this fallback in a very efficient way. When .NET Core does expose ARM intrinsics, the code could exploit them at which point the software fallback would rarely if ever be needed.
Project goals
- Increase ML.NET platform reach (x86, x64, ARM32, ARM64, etc.) by creating a single managed assembly with software fallbacks
- Increase ML.NET performance by using AVX instructions where available
- Validate .NET Hardware Intrinsics API and demonstrate performance is comparable to native code
I could have achieved the second goal by simply updating the native code to use AVX instructions, but by moving to managed code at the same time I could eliminate the need to build and ship a separate binary for each target architecture – it’s also usually easier to maintain managed code.
I was able to achieve all these goals.
Challenges
It was necessary to first familiarize myself with C# and .NET, and then my work included:
- use
Span<T>
in the base-layer implementation of CPU math operations in C#. If you’re unfamiliar withSpan<T>
, see this great MSDN magazine article C# – All About Span: Exploring a New .NET Mainstay and also the documentation. - enable switching between AVX, SSE, and software implementations depending on availability.
- correctly handle pointers in the managed code, and remove alignment assumptions made by some of the existing code
- use multitargeting to allow ML.NET continued to function on platforms that don’t have .NET Hardware Intrinsics APIs.
Multi-targeting
.NET Hardware Intrinsics will ship in .NET Core 3.0, which is currently in development. ML.NET also needs to run on .NET Standard 2.0 compliant platforms – such as .NET Framework 4.7.2 and .NET Core 2.1. In order to support both I chose to use multitargeting to create a single .csproj
file that targets both .NET Standard 2.0 and .NET Core 3.0.
- On .NET Standard 2.0, the system will use the original native implementation with SSE hardware intrinsics
- On .NET Core 3.0, the system will use the new managed implementation with AVX hardware intrinsics.
As the code was originally
In the original code, every trainer, learner, and transform used in machine learning ultimately called a SseUtils
wrapper method that performs a CPU math operation on input arrays, such as
MatMulDense
, which takes the matrix multiplication of two dense arrays interpreted as matrices, andSdcaL1UpdateSparse
, which performs the update step of the stochastic dual coordinate ascent for sparse arrays.
These wrapper methods assumed a preference for SSE instructions, and called a corresponding method in another class Thunk
, which serves as the interface between managed and native code and contains methods that directly invoke their native equivalents. These native methods in .cpp
files in turn implemented the CPU math operations with loops containing SSE hardware intrinsics.
Breaking out a managed code-path
To this code I added a new independent code path for CPU math operations that becomes active on .NET Core 3.0, and by keeping the original code path running on .NET Standard 2.0. All previous call sites of SseUtils
methods now called CpuMathUtils
methods of the same name instead, keeping the API signatures of CPU math operations the same.
CpuMathUtils
is a new partial class that contains two definitions for each public API representing CPU math operation, one of which is compiled only on .NET Standard 2.0 while the other, only on .NET Core 3.0. This conditional compilation feature creates two independent code paths for CpuMathUtils
methods. Those function definitions compiled on .NET Standard 2.0 call their SseUtils
counterparts directly, which essentially follow the original native code path.
Writing code with software fallback
On the other hand, the other function definitions compiled on .NET Core 3.0 switch to one of three implementations of the same CPU math operation, based on availability at runtime:
- an
AvxIntrinsics
method which implements the operation with loops containing AVX hardware intrinsics, - a
SseIntrinsics
method which implements the operation with loops containing SSE hardware intrinsics, and - a software fallback in case neither AVX nor SSE is supported.
You will commonly see this pattern whenever code uses .NET Hardware Intrinsics – for example, this is what the code looks like for adding a scalar to a vector:
If AVX is supported, it is preferred, otherwise SSE is used if available, otherwise the software fallback path. At runtime, the JIT will actually generate code for only one of these three blocks, as appropriate for the platform it finds itself on.
To give you an idea, here what the AVX implementation looks like that’s called by the method above:
You will notice that it operates on float
s in groups of 8 using AVX, then any group of 4 using SSE, and finally a software loop for any that remain. (There are potentially more efficient ways to do this, which I won’t discuss here – there will be future blog posts dedicated to .NET Hardware Intrinsics.)
You can see all my code on the dotnet/machinelearning repository.
Since the AvxIntrinsics
and SseIntrinsics
methods in managed code directly implement the CPU math operations analogous to the native methods originally in .cpp
files, the code change not only removes native dependencies but also simplifies the levels of abstraction between public APIs and base-layer hardware intrinsics.
After making this replacement I was able to use ML.NET to perform tasks such as train models with stochastic dual coordinate ascent, conduct hyperparameter tuning, and perform cross validation, on a Raspberry Pi, when previously ML.NET required an x86 CPU.
Here’s what the architecture looks like now (Figure 1):
Performance improvements
So what difference did this make to performance?
I wrote tests using Benchmark.NET to gather measurements.
First, I disabled the AVX code paths in order to fairly compare the native and managed implementations while both were using the same SSE instructions. As Figure 2 shows, the performance is closely comparable: on the large vectors the tests operate on, the overhead added by managed code is not significant.
Figure 2
Second, I enabled AVX support. Figure 3 shows that the average performance gain in microbenchmarks was about 20% over SSE alone.
Figure 3
Taking both together — the upgrade from the SSE implementation in native code to the AVX implementation in managed code — I measured an 18% improvement in the microbenchmarks. Some operations were up to 42% faster, while some others involving sparse inputs have potential for further optimization.
What ultimately matters of course is the performance for real scenarios. On .NET Core 3.0, training models of K-means clustering and logistic regression got faster by about 14% (Figure 4).
Figure 4
In closing
My summer internship experience with the .NET team has been rewarding and inspiring for me. My manager Dan and my mentors Santi and Eric gave me an opportunity to go hands-on with a real shipping project. I was able to work with other teams and external industry partners to optimize my code, and most importantly, as a software engineering intern with the .NET team, I was exposed to almost every step of the entire working cycle of a product enhancement, from idea generation to code review to product release with documentation.
I hope this has demonstrated how powerful .NET Hardware Intrinsics can be and I encourage you to consider opportunities to use them in your own projects when previews of .NET Core 3.0 become available.
Overview
In a recent post to software decision makers, I discussed reasons businesses should consider cross-platform native development over website development. You can read the previous Xamarin Tutorial post here.
In the post, I gave a case to use the Xamarin toolset, why it should be considered, and why it could be a good business and development decision for your organization.
In this Xamarin Tutorial series, I will be building a solution that can be used as a starting point for cross-platform applications using the Xamarin toolset. Today I will be focusing on the following:
- What is Xamarin?
- How to Setup the Xamarin development environment using Microsoft Visual Studio
- Briefly talk about iOS support
- Discuss Shared vs Portable Class Libraries (PCL) strategies and how to use both
- Connecting to your Mac to debug an iOS version of your application
- Using the Visual Studio iOS Simulator to debug your iOS application
Xamarin – What is it?
Before we start diving into creating our solution, I will include a snippet from the post mentioned above that gives you an overview of Xamarin. After this explanation, my assumption will be that you at least know what it is and why we are using it.
Xamarin is a Microsoft owned company that started with the engineers that created the popular Mono, Mono for Android and MonoTouch, which are cross platform implementations of the Common Language Infrastructure (CLI) and the Common Language Specifications, also known as .NET.
Xamarin uses a shared C#/.NET codebase along with either Xamarin Studio or Visual Studio, to write native Android, iOS, and Windows Apps. Did you understand that? Yes, native applications. Wow, so, all your code is 100% shared. Again, not exactly. But, close.
For most simple UI patterns, Xamarin.Forms allows you build native user interfaces for iOS, Android and Windows using 100% shared C#. It also includes dozens of controls and layouts which are mapped to native controls in their respective platform.
Depending on your application needs, however, you may need to access a platform specific feature, such as Live Tiles for Windows, or maybe you need to create a custom control that isn’t a native control for any of the platforms. In these scenarios, Xamarin provides a means to call into platform specific code. However, check this out, … wait for it … wait for it … it is still in C#.
So, as you can see, the App Logic and most of the user interface code is shared across all platforms. In fact, there is even a community of user-built components that you can leverage in your application using both NuGet and the Xamarin Component Store.
Development Environment – The Microsoft Way
Now that we have the basic definition and understanding of what Xamarin is, we can put that behind us and make sure that we have the tools necessary to start developing. For this, my plan is to stick with as many Microsoft technologies as possible.
Visual Studio
So, first in this Xamarin Tutorial, I am going to assume that you are using Windows 10 and have a flavor of Visual Studio 2015 installed on your machine. Even under that assumption, we need to make sure that you have the Xamarin tools installed. Luckily, this is easy.
First, make sure that you don’t have any instances of Visual Studio currently running.
Next, open your Windows Settings application and typeadd or remove in the search box. SelectAdd or remove programs from the dropdown list.
You will be taken to the Apps and Features section of settings. Scroll down and selectMicrosoft Visual Studio 2015. Now selectModify.
You will be prompted to give permission to the installer. Give it permission by selecting Yes. You should see the Installation program initializing.
If you didn’t shutdown Visual Studio 2015 before you selected Modify, the installer will notify you and recommend that you close Visual Studio now. If you did forget to close Visual Studio or skipped that step entirely, closeVisual Studio now and selectRetry.
If Visual Studio is closed, the installer should provide you an option to modify the current installation. SelectModify.
After selecting Modify, you will see a list of all the features currently installed. Since our goal in this Xamarin Tutorial series is to create a cross platform application, verify that all the Cross Platform Mobile Development features are enabled. We aren’t going to use all of features, but if you know you are going to do cross platform development and you have the space, install it now and forget it, you will have all the tools necessary for the future.
Since I already have the features installed, I can be assured that all the necessary tools are installed for me to start developing cross platform applications. If some of the features weren’t enabled for you, make sure they are and selectUpdate. This will install all the tools for you.
iOS Support
If we plan on having iOS support for our application, Xamarin.Forms does support it. So, yes, you can create iOS applications on Windows using C#.NET. However, you will need a networked Mac running OS X Yosemite (10.10) & above with XCode 7 installed. You will also need to install the Xamarin.iOS tools onto the Mac. The best way to do this is to use the Xamarin Unified Installer, which will install everything you need. You can view these instructions here.
I will assume that you have XCode and the Xamarin.iOS tools setup on your Mac. However, I will discuss how to attach to your Mac, build and run/debug the application later in the post.
One thing we can do right now is setup the permissions to allow us to debug our application on the iOS simulator on the Mac.
First, on your Mac, search for Remote Login in Spotlight.
Select Sharing. Select Remote Login and make sure that your account is in the list of Allow Access for: Only these users. I am an Administrator on my Mac, so I will just allow all Administrators.
NOTE: You could allow All Users to have remote access, but, I am not sure that is a good idea.
Your Mac should now be discoverable in Visual Studio. Again, we will talk more about this later.
Example Visual Studio For Mac Building Backend Api Project Management
Create a New Project
Blank Application
Now we can create our new project. Open Visual Studio, select File, New, Project…
Next, select Installed, Templates, Visual C#, Cross-Platform. Then, select Cross Platform App (Xamarin.Forms or Native). Enter the name of your project. Make sure the directory is correct and then selectOK.
Another dialog prompting for the type of cross-platform project will be displayed. Select Blank App, Xamarin.Forms, Shared Project and then selectOK.
Visual Studio
Visual Studio will start creating your Xamarin solution. However, since we are targeting Universal Windows Platform applications in our project, you will be prompted for your Target and Minimum versions of Windows. I have chosen to target Windows 10 Anniversary Edition with a Minimum version of Windows 10 (Build 10586). Once you have made your selection, select OK.
You will also probably see the following dialog while it is creating the solution.
When it is finished, you should notice that there are several projects in your solution. One for each of the platforms we will target with our application.
Along with the iOS, Android and UWP projects, you should also notice that there is a Shared project. I know, I kind of blew past that part when I had you select the Code Sharing Strategy shared project. I did this on purpose, I will explain this in more detail now.
Xamarin uses a couple of strategies for sharing code within our Xamarin solution: Shared and Portable Class Library (PCL).
Shared Strategy
The shared strategy basically takes each file in the shared project and compiles it under each of the other projects. Think of it as making a copy of the files in the shared project into each specific platform project and then doing a build. You can still do platform specific code in the shared project by using #if compiler directives, but be cautious, your code can, and probably will, become ugly fast.
Note: the shared project isn’t really a traditional project that gets built into an assembly. You can’t actually build it.
Portable Class Libraries (PCL)
With portable class libraries, the code is compiled separately and referenced in each project like any normal class library. The big difference here is that you have access to a subset of .NET that is compatible with all the target platforms. So, for example, you could use System.Net.Http, but trying to access hardware, such as, the camera API is not available. You could, however, use a generalized interface that uses dependency injection.
Both Shared and Portable?
So, as you can see, each strategy mentioned above, contains some pros and cons. So, it really depends on the type of application and how much external sharing you are going to need to do with the code. Simply put, if you are going to share code outside of the application itself, PCL’s are a good choice. However, if this is a one-time application with no externally shared code, the shared strategy would be a good choice.
That being stated, what if we want to use both? Can we do that? To answer your question, yes. What if you have a lot of shared code between applications, but you also have a significant amount that is just shared across your specific application?
In fact, let’s add a PCL to our project for any code that we might want to share with other applications we write in the future. We won’t do anything with it right now other than wire it up for use in my next blog post.
First, right-click on the solution, selectAdd and then selectNewProject…
Example Visual Studio For Mac Building Backend Api Project Fitness
From here, we want to repeat the same steps we used to create the solution, but in this case, we want to select a class library. Select Installed, Cross-Platform, Class Library (Xamarin.Forms). Enter the name of your shared class and selectOK.
Okay, now, one thing you should know is, by default, the project will add a Xamarin ContentPage, XamarinBlog.CommonServices.cs. You can go ahead and delete it now.
Okay, we now have a portable class library in our solution, however, it isn’t being referenced. So, go ahead and reference it in each of the platform specific projects by right clicking on references and selectingAddReference…
SelectProjects, then Solution, then select your new PCL from the list. Finally, selectOK.
Okay, now that we have our PCL referenced in each project, you should be able to build most of the projects. As far as the iOS project, we really haven’t talked about how to connect to your Mac for building, so let’s do that quickly.
Connecting to the Mac
For us to build our iOS project, we will need to connect your Visual Studio iOS project to a Mac. To do this for the first time, all you do is attempt to build the project. Right-click on the project and selectBuild. If you haven’t connected before, Visual Studio will display instructions for setting up the remote login functionality on your Mac. Since we already did this earlier in the post, we will skip them and selectNext. If you would like, you can turn off the instructions for next time, however, if you are like me, I forget the “setup once and forget” things, so I usually leave mine unchecked.
You will now be prompted to pick your Mac. For it to show up in the list, you must have setup remote access properly and the Mac bust be on the same network as Visual Studio. Select your Mac and then selectConnect.
Next, you will be prompted for your username and password. Enter your credentials and selectLogin.
Once you have selected Login, it will attempt to connect to your Mac. If it is successful, you will see a link under the Icon for the machine you selected. Once you see this, selectClose.
Now, go ahead and try to build. I should build successfully if everything on your Mac is setup correctly.
Can I see Something?
I know, we have done a lot up to this point and we haven’t seen a darn thing. Well, before we run the application, I do want to mention a couple more things. First, let’s look at where this whole application starts in code. Where is the application object for this thing?
In the shared project, XamarinBlog, open App.xaml.cs.
Notice this is where our Application object for all our projects resides. How do we know what page to load first? Check out the constructor. Notice that we assign XamarinBlog.MainPage to the MainPage property of our application. Also, you may have noticed that there are a number of events that are created for us: OnStart(), OnSleep() and OnResume(). These are application lifecycle events that get fired for each platform. We will probably talk more about these in later posts in this series.
Let’s look at the XamarinBlog.MainPage object in Mainpage.xaml and see if we can figure out what this page is going to be presenting us. Select MainPage.xaml.
Looking at the markup, we see we are creating a ContentPage with a label, that has the text ‘Welcome to Xamarin Forms!”, and it is centered in the middle of the page.
Now that we know what it is supposed to do, let’s see it in action. Build and run the applicationfor each platform and see what you get. It should look something like the following:
Cool, right? Three platforms, mostly the same code. Well at least the UI, so far.
Using Visual Studio iOS Simulator
It is nice to be able to debug on your Mac, but I must admit, it is kind of a pain at times to be forced to sit by the machine to test your application. Well, a cool new feature for Visual Studio is the Visual Studio iOS Simulator. This add-in for Visual Studio allows us to debug our iOS version of the app right on our computer. So, you don’t need to be near your Mac to do the debugging. You can do it right on your PC.
To get the add-in, download the installer here. You might have to restart Visual Studio for changes to take effect. Once you do, make sure that you selectiPhoneSimulator and run the application again.
You should see the Visual Studio iOS Simulator with your application.
If for some reason, you would like to disable the Visual Studio add-in and go back to debugging your iOS application on the Mac you can do so. All you need to do is selectTools from the main menu and then selectOptions…
Scroll down to the Xamarin tab and select iOS Settings. Uncheck the Remote Simulator to Windows checkbox and selectOK.
Now, you should be able to debug on your Mac again.
Summary
So, to summarize what we learned in the first part of our Xamarin Tutorial series:
- We answered the question, “What is Xamarin?”
- We Setup the development environment using Microsoft Visual Studio
- Briefly talked about iOS support in Xamarin and Visual Studio
- Pointed out the differences between the Shared and Portable Class Libraries (PCL) strategies and how to use both
- Demonstrated how to connect to your Mac to debug the iOS version of your application
- Installed Visual Studio iOS Simulator and ran our iOS application on our PC
In Part 2 of this Xamarin Tutorial series, we will talk about implementing the Model-View-ViewModel pattern using the MVVM Light Toolkit to maintain a solid separation of concerns. So, stop back and continue your journey with me on developing cross-platform applications using Xamarin.
I hope you enjoyed this post. If so, please feel free to share with others.
Building a mobile application and need assistance? Intertech knows a thing or two about Xamarin. We provide Xamarin Consulting along with other mobile consulting services to your team. See how we can help!