Skip to content

Commit 67c6e73

Browse files
authored
Merge pull request #455 from microsoft/user/numform/adapter_selection
Add Adapter Selection Sample
2 parents 4fa07c9 + 4518c7f commit 67c6e73

File tree

14 files changed

+318
-4
lines changed

14 files changed

+318
-4
lines changed

Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
3737
<PropertyGroup>
3838
<ProjectGuid>dea7791f-55cf-4ed5-bc99-3870997b1242</ProjectGuid>
39-
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
39+
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
4040
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
4141
<AssetTargetFallback>net5.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
4242
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>

Samples/WinMLSamplesGallery/WinMLSamplesGallery/Pages/SampleBasePage.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
3737
case "EncryptedModel":
3838
SampleFrame.Navigate(typeof(Samples.EncryptedModel));
3939
break;
40+
case "AdapterSelection":
41+
SampleFrame.Navigate(typeof(Samples.AdapterSelection));
42+
break;
4043
}
4144
if (sampleMetadata.Docs.Count > 0)
4245
DocsHeader.Visibility = Visibility.Visible;

Samples/WinMLSamplesGallery/WinMLSamplesGallery/SampleMetadata/SampleMetadata.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@
7171
"CSharpGithubLink": "https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/EncryptedModel/EncryptedModel.xaml.cs",
7272
"Docs": [],
7373
"IsRecentlyAdded": true
74+
},
75+
{
76+
"Title": "Adapter Selection",
77+
"DescriptionShort": "Select different adapters based on your power and performance needs.",
78+
"Description": "The sample showcases how to use Windows ML with different adapters that have tradeoffs between power and performance.",
79+
"Icon": "\uE155",
80+
"Tag": "AdapterSelection",
81+
"XAMLGithubLink": "https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/AdapterSelection/AdapterSelection.xaml",
82+
"CSharpGithubLink": "https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/AdapterSelection/AdapterSelection.xaml.cs",
83+
"Docs": [],
84+
"IsRecentlyAdded": true
7485
}
7586
]
7687
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<Page
2+
x:Class="WinMLSamplesGallery.Samples.AdapterSelection"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7+
xmlns:local_controls="using:WinMLSamplesGallery.Controls"
8+
xmlns:local_samples="using:WinMLSamplesGallery.Samples"
9+
mc:Ignorable="d"
10+
FontFamily="Arial">
11+
12+
<Page.Resources>
13+
<x:String x:Key="SourceGitHubURL">
14+
https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/AdapterList.cpp
15+
</x:String>
16+
</Page.Resources>
17+
18+
<StackPanel Margin="0,20,0,0">
19+
<Border BorderBrush="Gray" BorderThickness="2" CornerRadius="5">
20+
<ListView x:Name="AdapterListView" SelectedIndex="0" SelectionChanged="ChangeAdapter">
21+
<ListView.ItemContainerStyle>
22+
<Style TargetType="ListViewItem">
23+
<Setter Property="BorderBrush" Value="LightGray" />
24+
<Setter Property="BorderThickness" Value="0,0,0,1" />
25+
</Style>
26+
</ListView.ItemContainerStyle>
27+
</ListView>
28+
</Border>
29+
<ComboBox x:Name="CodeSnippetComboBox" SelectedIndex="0" BorderBrush="#dbdbdb" Header="" Width="70" FontSize="18" Margin="0,20,0,0"
30+
Typography.Capitals="AllSmallCaps" Typography.StylisticSet4="True"
31+
HorizontalAlignment="Right">
32+
<x:String>C#</x:String>
33+
</ComboBox>
34+
<Grid x:Name="CodeSnippet" Background="#F6F6F6" BorderBrush="#dbdbdb" BorderThickness="1" CornerRadius="5" Padding="15,20,15,22">
35+
<TextBlock x:Name="TestName" FontSize="14" FontFamily="Consolas">
36+
<Run Foreground="#3562FF">var </Run>
37+
<Run Foreground="#1684B2">device</Run>
38+
<Run> = </Run>
39+
<Run Foreground="#3562FF">new </Run>
40+
<Run Foreground="#1F9D00">LearningModelDevice</Run><Run>(</Run><Run Foreground="#005c11">
41+
LearningModelDeviceKind.</Run><Run x:Name="selectedDeviceKind" Foreground="#1684B2"></Run><Run>);</Run>
42+
</TextBlock>
43+
</Grid>
44+
<TextBlock x:Name="ViewSourCodeText" Visibility="Collapsed" Margin="0,40,0,0" FontWeight="Bold" TextWrapping="Wrap">
45+
For information on how to use a custom adapter with Windows ML
46+
<Hyperlink TextDecorations="None" NavigateUri="{StaticResource SourceGitHubURL}" ToolTipService.ToolTip="{StaticResource SourceGitHubURL}">
47+
view source code.
48+
</Hyperlink>
49+
</TextBlock>
50+
</StackPanel>
51+
</Page>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using Microsoft.AI.MachineLearning;
2+
using Microsoft.UI.Xaml;
3+
using Microsoft.UI.Xaml.Controls;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Threading.Tasks;
8+
using Windows.Graphics.Imaging;
9+
using Windows.Media;
10+
using Windows.Storage;
11+
using WinMLSamplesGalleryNative;
12+
13+
namespace WinMLSamplesGallery.Samples
14+
{
15+
public sealed partial class AdapterSelection : Page
16+
{
17+
List<string> adapter_options;
18+
LearningModelDevice device;
19+
public AdapterSelection()
20+
{
21+
this.InitializeComponent();
22+
adapter_options = new List<string> {
23+
"Cpu",
24+
"DirectX",
25+
"DirectXHighPerformance",
26+
"DirectXMinPower"
27+
};
28+
device = new LearningModelDevice(LearningModelDeviceKind.Cpu);
29+
selectedDeviceKind.Text = "Cpu";
30+
31+
var adapters_arr = WinMLSamplesGalleryNative.AdapterList.GetAdapters();
32+
var adapters = RemoveMicrosoftBasicRenderDriver(adapters_arr);
33+
34+
adapter_options.AddRange(adapters);
35+
AdapterListView.ItemsSource = adapter_options;
36+
}
37+
38+
private void ChangeAdapter(object sender, RoutedEventArgs e)
39+
{
40+
var device_kind_str = adapter_options[AdapterListView.SelectedIndex];
41+
if (AdapterListView.SelectedIndex < 4)
42+
{
43+
device = new LearningModelDevice(
44+
GetLearningModelDeviceKind(device_kind_str));
45+
toggleCodeSnippet(true);
46+
}
47+
else
48+
{
49+
device = WinMLSamplesGalleryNative.AdapterList.CreateLearningModelDeviceFromAdapter(device_kind_str);
50+
toggleCodeSnippet(false);
51+
}
52+
}
53+
54+
private LearningModelDeviceKind GetLearningModelDeviceKind(string device_kind_str)
55+
{
56+
selectedDeviceKind.Text = device_kind_str;
57+
if (device_kind_str == "CPU")
58+
{
59+
return LearningModelDeviceKind.Cpu;
60+
}
61+
else if (device_kind_str == "DirectX")
62+
{
63+
return LearningModelDeviceKind.DirectX;
64+
}
65+
else if (device_kind_str == "DirectXHighPerformance")
66+
{
67+
return LearningModelDeviceKind.DirectXHighPerformance;
68+
}
69+
else
70+
{
71+
return LearningModelDeviceKind.DirectXMinPower;
72+
}
73+
}
74+
75+
private void toggleCodeSnippet(bool show)
76+
{
77+
if (show)
78+
{
79+
CodeSnippet.Visibility = Visibility.Visible;
80+
CodeSnippetComboBox.Visibility = Visibility.Visible;
81+
ViewSourCodeText.Visibility = Visibility.Collapsed;
82+
} else
83+
{
84+
CodeSnippet.Visibility = Visibility.Collapsed;
85+
CodeSnippetComboBox.Visibility = Visibility.Collapsed;
86+
ViewSourCodeText.Visibility = Visibility.Visible;
87+
}
88+
}
89+
90+
private List<string> RemoveMicrosoftBasicRenderDriver(string[] adapters_arr)
91+
{
92+
List<string> adapters = new List<string>(adapters_arr);
93+
for (int i = 0; i < adapters.Count; i++)
94+
{
95+
if(adapters[i] == "Microsoft Basic Render Driver")
96+
{
97+
adapters.RemoveAt(i);
98+
break;
99+
}
100+
}
101+
return adapters;
102+
}
103+
}
104+
}
916 KB
Loading
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Windows ML Samples Gallery: Adapter Selection
2+
Select different adapters based on your power and performance needs.
3+
4+
The sample showcases how to use Windows ML with different adapters that have tradeoffs between power and performance.
5+
6+
<img src="Docs/AdapterSelectionScreenshot.png" width="650"/>
7+
8+
- [Getting Started](#getting-started)
9+
- [Feedback](#feedback)
10+
- [External Links](#external-links)
11+
12+
## Getting Started
13+
- Check out the [source](https://github.com/microsoft/Windows-Machine-Learning/blob/master/adapter_selection/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/AdapterSelection/AdapterSelection.xaml.cs).
14+
- Learn how to [get a list of adapters using DXCore](https://github.com/microsoft/Windows-Machine-Learning/blob/master/adapter_selection/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/AdapterList.cpp#L12) to your session.
15+
- Learn how to [create learning model devices from adapters](https://github.com/microsoft/Windows-Machine-Learning/blob/master/adapter_selection/Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative/AdapterList.cpp#L41).
16+
17+
## Feedback
18+
Please file an issue [here](https://github.com/microsoft/Windows-Machine-Learning/issues/new) if you encounter any issues with the Windows ML Samples Gallery or wish to request a new sample.
19+
20+
## External Links
21+
- [Windows ML Library (WinML)](https://docs.microsoft.com/en-us/windows/ai/windows-ml/)
22+
- [DirectML](https://github.com/microsoft/directml)
23+
- [ONNX Model Zoo](https://github.com/onnx/models)
24+
- [Windows UI Library (WinUI)](https://docs.microsoft.com/en-us/windows/apps/winui/)

Samples/WinMLSamplesGallery/WinMLSamplesGallery/WinMLSamplesGallery.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<OutputType>WinExe</OutputType>
4-
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
4+
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
55
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
66
<RootNamespace>WinMLSamplesGallery</RootNamespace>
77
<ApplicationManifest>app.manifest</ApplicationManifest>
@@ -160,6 +160,7 @@
160160

161161
<ItemGroup>
162162
<Folder Include="LargeModels\" />
163+
<Folder Include="Samples\AdapterSelection\Docs\" />
163164
</ItemGroup>
164165

165166
<Target Name="DownloadContentFiles" BeforeTargets="BeforeBuild">

Samples/WinMLSamplesGallery/WinMLSamplesGalleryNative.Interop/WinMLSamplesGalleryNative.Interop.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<ProjectName>WinMLSamplesGalleryNative.Interop</ProjectName>
5-
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
5+
<TargetFramework>net5.0-windows10.0.19041.0</TargetFramework>
66
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
88
<Platforms>x86;x64;arm64;</Platforms>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "pch.h"
2+
#include "AdapterList.h"
3+
#include "AdapterList.g.cpp"
4+
#include <initguid.h>
5+
#include <dxcore.h>
6+
#include "d3d12.h"
7+
#include "winrt/Microsoft.AI.MachineLearning.h"
8+
#include "Microsoft.AI.MachineLearning.Native.h"
9+
10+
namespace winrt::WinMLSamplesGalleryNative::implementation
11+
{
12+
winrt::com_ptr<IDXCoreAdapterList> GetDXCoreAdapterList() {
13+
// Create an adapter factory
14+
winrt::com_ptr<IDXCoreAdapterFactory> adapterFactory;
15+
winrt::check_hresult(::DXCoreCreateAdapterFactory(adapterFactory.put()));
16+
17+
// Retrieve an adapter list
18+
winrt::com_ptr<IDXCoreAdapterList> d3D12CoreComputeAdapters;
19+
GUID attributes[]{ DXCORE_ADAPTER_ATTRIBUTE_D3D12_CORE_COMPUTE };
20+
winrt::check_hresult(
21+
adapterFactory->CreateAdapterList(_countof(attributes),
22+
attributes,
23+
d3D12CoreComputeAdapters.put()));
24+
return d3D12CoreComputeAdapters;
25+
}
26+
27+
winrt::com_array<hstring> AdapterList::GetAdapters() {
28+
winrt::com_ptr<IDXCoreAdapterList> d3D12CoreComputeAdapters = GetDXCoreAdapterList();
29+
30+
// Get the adapter descriptions from the adapters in the list
31+
const uint32_t count{ d3D12CoreComputeAdapters->GetAdapterCount() };
32+
com_array<hstring> driver_descriptions = com_array<hstring>(count);
33+
for (uint32_t i = 0; i < count; ++i)
34+
{
35+
winrt::com_ptr<IDXCoreAdapter> candidateAdapter;
36+
winrt::check_hresult(
37+
d3D12CoreComputeAdapters->GetAdapter(i, candidateAdapter.put()));
38+
CHAR description[128];
39+
candidateAdapter->GetProperty(DXCoreAdapterProperty::DriverDescription, sizeof(description), description);
40+
driver_descriptions[i] = to_hstring(description);
41+
}
42+
43+
return driver_descriptions;
44+
}
45+
46+
winrt::Microsoft::AI::MachineLearning::LearningModelDevice AdapterList::CreateLearningModelDeviceFromAdapter(winrt::hstring description) {
47+
winrt::com_ptr<IDXCoreAdapterList> d3D12CoreComputeAdapters = GetDXCoreAdapterList();
48+
49+
// Find the adapter in the list with the matching description
50+
const uint32_t count{ d3D12CoreComputeAdapters->GetAdapterCount() };
51+
for (uint32_t i = 0; i < count; ++i)
52+
{
53+
winrt::com_ptr<IDXCoreAdapter> candidateAdapter;
54+
winrt::check_hresult(
55+
d3D12CoreComputeAdapters->GetAdapter(i, candidateAdapter.put()));
56+
CHAR driver_description[128];
57+
candidateAdapter->GetProperty(DXCoreAdapterProperty::DriverDescription, sizeof(driver_description), driver_description);
58+
hstring hstr_driver_description = to_hstring(driver_description);
59+
60+
if (description == hstr_driver_description) {
61+
// create D3D12Device
62+
com_ptr<IUnknown> spIUnknownAdapter;
63+
candidateAdapter->QueryInterface(IID_IUnknown, spIUnknownAdapter.put_void());
64+
com_ptr<ID3D12Device> spD3D12Device;
65+
D3D12CreateDevice(spIUnknownAdapter.get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), spD3D12Device.put_void());
66+
67+
// create D3D12 command queue from device
68+
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
69+
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
70+
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
71+
com_ptr<ID3D12CommandQueue> spCommandQueue;
72+
spD3D12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(spCommandQueue.put()));
73+
74+
// create LearningModelDevice from command queue
75+
com_ptr<ILearningModelDeviceFactoryNative> dFactory =
76+
get_activation_factory<winrt::Microsoft::AI::MachineLearning::LearningModelDevice, ILearningModelDeviceFactoryNative>();
77+
com_ptr<::IUnknown> spLearningDevice;
78+
dFactory->CreateFromD3D12CommandQueue(spCommandQueue.get(), spLearningDevice.put());
79+
return spLearningDevice.as<winrt::Microsoft::AI::MachineLearning::LearningModelDevice>();
80+
}
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)