Skip to content

Commit

Permalink
Merge pull request #158 from microsoft/alzollin/wcrapis
Browse files Browse the repository at this point in the history
Added support for WCR APIs
  • Loading branch information
nmetulev authored Feb 21, 2025
2 parents b005eb5 + c308125 commit 4892f01
Show file tree
Hide file tree
Showing 151 changed files with 5,211 additions and 889 deletions.
3 changes: 3 additions & 0 deletions AIDevGallery.SourceGenerator/Models/ApiDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ internal class ApiDefinition
public required string Id { get; init; }
public required string Name { get; init; }
public required string Icon { get; init; }
public required string IconGlyph { get; init; }
public required string Description { get; init; }
public required string ReadmeUrl { get; init; }
public required string License { get; init; }
public required string SampleIdToShowInDocs { get; init; }
}
3 changes: 2 additions & 1 deletion AIDevGallery.SourceGenerator/Models/HardwareAccelerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ internal enum HardwareAccelerator
{
CPU,
DML,
QNN
QNN,
WCRAPI
}
6 changes: 4 additions & 2 deletions AIDevGallery.SourceGenerator/ModelsSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ internal class ModelSourceGenerator : IIncrementalGenerator
public void Initialize(IncrementalGeneratorInitializationContext context)
{
IncrementalValuesProvider<AdditionalText> modelJsons = context.AdditionalTextsProvider.Where(
static file => file.Path.EndsWith(".json") &&
Path.GetFileName(Path.GetDirectoryName(file.Path)).Equals("ModelsDefinitions", StringComparison.OrdinalIgnoreCase));
static file => file.Path.EndsWith(".json") && file.Path.Contains(@"\Samples\Definitions\"));

var pathsAndContents = modelJsons.Select((text, cancellationToken) =>
(text.Path, Content: text.GetText(cancellationToken)!.ToString(), CancellationToken: cancellationToken))
Expand Down Expand Up @@ -322,8 +321,11 @@ private void GenerateApiDefinitionDetails(StringBuilder sourceBuilder, Dictionar
Id = "{{apiDefinition.Id}}",
Name = "{{apiDefinition.Name}}",
Icon = "{{apiDefinition.Icon}}",
IconGlyph = "{{apiDefinition.IconGlyph}}",
Description = "{{apiDefinition.Description}}",
ReadmeUrl = "{{apiDefinition.ReadmeUrl}}",
License = "{{apiDefinition.License}}",
{{(!string.IsNullOrWhiteSpace(apiDefinition.SampleIdToShowInDocs) ? $"SampleIdToShowInDocs = \"{apiDefinition.SampleIdToShowInDocs}\"" : string.Empty)}}
}
},
"""");
Expand Down
38 changes: 32 additions & 6 deletions AIDevGallery.SourceGenerator/SamplesSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private void ExecuteSharedCodeEnumGeneration(SourceProductionContext context, Im
{
var filePath = type!.Locations[0].SourceTree?.FilePath;

if (filePath != null)
if (filePath != null && !filePath.Contains(@"\obj\"))
{
if (!filePaths.Contains(filePath))
{
Expand All @@ -66,7 +66,15 @@ private void ExecuteSharedCodeEnumGeneration(SourceProductionContext context, Im
foreach (var filePath in filePaths)
{
var fileName = Path.GetFileNameWithoutExtension(filePath);
if (File.Exists(Path.ChangeExtension(filePath, ".xaml")))
var extension = Path.GetExtension(filePath);
var filePathWithoutExtension = filePath.Substring(0, filePath.Length - extension.Length);
if (fileName.EndsWith(".xaml", StringComparison.InvariantCultureIgnoreCase) && File.Exists(filePathWithoutExtension))
{
fileName = Path.GetFileNameWithoutExtension(filePathWithoutExtension);
sourceBuilder.AppendLine($" {fileName}Cs,");
sourceBuilder.AppendLine($" {fileName}Xaml,");
}
else if (File.Exists(Path.ChangeExtension(filePath, ".xaml")))
{
sourceBuilder.AppendLine($" {fileName}Cs,");
sourceBuilder.AppendLine($" {fileName}Xaml,");
Expand All @@ -89,14 +97,22 @@ private void ExecuteSharedCodeEnumGeneration(SourceProductionContext context, Im
{
var fileName = Path.GetFileNameWithoutExtension(filePath);
var filePathXaml = Path.ChangeExtension(filePath, ".xaml");
if (File.Exists(filePathXaml))
var extension = Path.GetExtension(filePath);
var filePathWithoutExtension = filePath.Substring(0, filePath.Length - extension.Length);
if (fileName.EndsWith(".xaml", StringComparison.InvariantCultureIgnoreCase) && File.Exists(filePathWithoutExtension))
{
sourceBuilder.AppendLine($" SharedCodeEnum.{Path.GetFileNameWithoutExtension(filePath)}Xaml => \"{Path.GetFileName(filePathXaml)}\",");
sourceBuilder.AppendLine($" SharedCodeEnum.{Path.GetFileNameWithoutExtension(filePath)}Cs => \"{Path.GetFileName(filePath)}\",");
fileName = Path.GetFileNameWithoutExtension(fileName);
sourceBuilder.AppendLine($" SharedCodeEnum.{fileName}Cs => \"{fileName}.xaml.cs\",");
sourceBuilder.AppendLine($" SharedCodeEnum.{fileName}Xaml => \"{fileName}.xaml\",");
}
else if (File.Exists(filePathXaml))
{
sourceBuilder.AppendLine($" SharedCodeEnum.{fileName}Xaml => \"{Path.GetFileName(filePathXaml)}\",");
sourceBuilder.AppendLine($" SharedCodeEnum.{fileName}Cs => \"{Path.GetFileName(filePath)}\",");
}
else
{
sourceBuilder.AppendLine($" SharedCodeEnum.{Path.GetFileNameWithoutExtension(filePath)} => \"{Path.GetFileName(filePath)}\",");
sourceBuilder.AppendLine($" SharedCodeEnum.{fileName} => \"{Path.GetFileName(filePath)}\",");
}
}

Expand All @@ -111,6 +127,16 @@ private void ExecuteSharedCodeEnumGeneration(SourceProductionContext context, Im
{
var fileName = Path.GetFileNameWithoutExtension(filePath);
var filePathXaml = Path.ChangeExtension(filePath, ".xaml");
var extension = Path.GetExtension(filePath);
var filePathWithoutExtension = filePath.Substring(0, filePath.Length - extension.Length);

// handle .xaml.cs files
if (File.Exists(filePathWithoutExtension))
{
filePathXaml = filePathWithoutExtension;
fileName = Path.GetFileNameWithoutExtension(fileName);
}

if (File.Exists(filePathXaml))
{
var fileContentXaml = XamlSourceCleanUp(File.ReadAllText(filePathXaml));
Expand Down
81 changes: 60 additions & 21 deletions AIDevGallery.UnitTests/ProjectGeneratorUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -62,7 +63,9 @@ private class SampleUIData : INotifyPropertyChanged
{
private Brush? statusColor;

public required string SampleName { get; init; }
public required Sample Sample { get; init; }
public required Dictionary<ModelType, (string CachedModelDirectoryPath, string ModelUrl, HardwareAccelerator HardwareAccelerator)> CachedModelsToGenerator { get; init; }
public Brush? StatusColor
{
get => statusColor;
Expand Down Expand Up @@ -93,11 +96,7 @@ public async Task GenerateForAllSamples()

UITestMethodAttribute.DispatcherQueue?.TryEnqueue(() =>
{
source = SampleDetails.Samples.Select(s => new SampleUIData
{
Sample = s,
StatusColor = new SolidColorBrush(Colors.LightGray)
}).ToList();
source = SampleDetails.Samples.SelectMany(s => GetAllForSample(s)).ToList();

green = new SolidColorBrush(Colors.Green);
red = new SolidColorBrush(Colors.Red);
Expand All @@ -119,49 +118,89 @@ public async Task GenerateForAllSamples()

// write test count
TestContext.WriteLine($"Running {source.Count} tests");

int currentId = 0;
await Parallel.ForEachAsync(source, new ParallelOptions { MaxDegreeOfParallelism = 4 }, async (item, ct) =>
{
listView.DispatcherQueue.TryEnqueue(() =>
{
item.StatusColor = yellow;
});

var success = await GenerateForSample(item.Sample, ct);
Interlocked.Increment(ref currentId);

TestContext.WriteLine($"Built {item.Sample.Name} with status {success}");
Debug.WriteLine($"Built {item.Sample.Name} with status {success}");
var success = await GenerateForSample(currentId, item, ct);

TestContext.WriteLine($"Built {item.SampleName} with status {success}");
Debug.WriteLine($"Built {item.SampleName} with status {success}");

listView.DispatcherQueue.TryEnqueue(() =>
{
item.StatusColor = success ? green : red;
});
successDict.Add(item.Sample.Name, success);
successDict.Add(item.SampleName, success);
});

successDict.Should().AllSatisfy(kvp => kvp.Value.Should().BeTrue($"{kvp.Key} should build successfully"));
}

private async Task<bool> GenerateForSample(Sample sample, CancellationToken cancellationToken)
private static IEnumerable<SampleUIData> GetAllForSample(Sample s)
{
var modelsDetails = ModelDetailsHelper.GetModelDetails(sample);
var modelsDetails = ModelDetailsHelper.GetModelDetails(s);

if (modelsDetails[0].ContainsKey(ModelType.LanguageModels) &&
modelsDetails[0].ContainsKey(ModelType.PhiSilica))
{
yield return new SampleUIData
{
Sample = s,
SampleName = $"{s.Name} GenAI",
CachedModelsToGenerator = GetModelsToGenerator(s, modelsDetails, modelsDetails[0].First(md => md.Key == ModelType.LanguageModels)),
StatusColor = new SolidColorBrush(Colors.LightGray)
};

ModelDetails modelDetails1 = modelsDetails[0].Values.First().First();
Dictionary<ModelType, (string CachedModelDirectoryPath, string ModelUrl, HardwareAccelerator HardwareAccelerator)> cachedModelsToGenerator = new()
yield return new SampleUIData
{
Sample = s,
SampleName = $"{s.Name} PhiSilica",
CachedModelsToGenerator = GetModelsToGenerator(s, modelsDetails, modelsDetails[0].First(md => md.Key == ModelType.PhiSilica)),
StatusColor = new SolidColorBrush(Colors.LightGray)
};
}
else
{
[sample.Model1Types.First()] = ("FakePath", modelsDetails[0].Values.First().First().Url, modelDetails1.HardwareAccelerators.First())
};
yield return new SampleUIData
{
Sample = s,
SampleName = s.Name,
CachedModelsToGenerator = GetModelsToGenerator(s, modelsDetails, modelsDetails[0].First()),
StatusColor = new SolidColorBrush(Colors.LightGray)
};
}

if (sample.Model2Types != null && modelsDetails.Count > 1)
static Dictionary<ModelType, (string CachedModelDirectoryPath, string ModelUrl, HardwareAccelerator HardwareAccelerator)> GetModelsToGenerator(Sample s, List<Dictionary<ModelType, List<ModelDetails>>> modelsDetails, KeyValuePair<ModelType, List<ModelDetails>> keyValuePair)
{
ModelDetails modelDetails2 = modelsDetails[1].Values.First().First();
cachedModelsToGenerator[sample.Model2Types.First()] = ("FakePath", modelDetails2.Url, modelDetails2.HardwareAccelerators.First());
Dictionary<ModelType, (string CachedModelDirectoryPath, string ModelUrl, HardwareAccelerator HardwareAccelerator)> cachedModelsToGenerator = new();

ModelDetails modelDetails1 = keyValuePair.Value.First();
cachedModelsToGenerator[keyValuePair.Key] = (modelDetails1.Url, modelDetails1.Url, modelDetails1.HardwareAccelerators.First());

if (s.Model2Types != null && modelsDetails.Count > 1)
{
ModelDetails modelDetails2 = modelsDetails[1].Values.First().First();
cachedModelsToGenerator[s.Model2Types.First()] = (modelDetails2.Url, modelDetails2.Url, modelDetails2.HardwareAccelerators.First());
}

return cachedModelsToGenerator;
}
}

var projectPath = await generator.GenerateAsync(sample, cachedModelsToGenerator, false, TmpPathProjectGenerator, cancellationToken);
private async Task<bool> GenerateForSample(int id, SampleUIData sampleUIData, CancellationToken cancellationToken)
{
var outputPath = Path.Join(TmpPathProjectGenerator, id.ToString(CultureInfo.InvariantCulture));
var projectPath = await generator.GenerateAsync(sampleUIData.Sample, sampleUIData.CachedModelsToGenerator, false, outputPath, cancellationToken);

var safeProjectName = Path.GetFileName(projectPath);
string logFileName = $"build_{safeProjectName}.log";
string logFileName = $"build_{id}_{sampleUIData.SampleName.Replace(' ', '_')}.log";

var arch = DeviceUtils.IsArm64() ? "arm64" : "x64";

Expand Down
2 changes: 1 addition & 1 deletion AIDevGallery.UnitTests/UnitTestApp.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<DataTemplate x:Key="SampleItemTemplate">
<Grid>
<Border Background="{Binding StatusColor}">
<TextBlock Text="{Binding Sample.Name}" FontSize="16"/>
<TextBlock Text="{Binding SampleName}" FontSize="16"/>
</Border>
</Grid>
</DataTemplate>
Expand Down
2 changes: 2 additions & 0 deletions AIDevGallery/AIDevGallery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,6 @@
<UserProperties />
</VisualStudio>
</ProjectExtensions>

<Import Project="$(MSBuildThisFileDirectory)\WinAppSDKSelfContainedFix.targets" Condition="'$(WindowsAppSDKSelfContained)'=='true'" />
</Project>
11 changes: 7 additions & 4 deletions AIDevGallery/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
x:Class="AIDevGallery.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AIDevGallery">
xmlns:local="using:AIDevGallery"
xmlns:models="using:AIDevGallery.Models">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="/Styles/Button.xaml" />
<ResourceDictionary Source="/Styles/Colors.xaml" />
<ResourceDictionary Source="/Styles/ComboBox.xaml" />
<ResourceDictionary Source="/Styles/Card.xaml" />
<ResourceDictionary Source="/Styles/NavigationView.xaml" />
<ResourceDictionary Source="/Styles/SelectorBar.xaml" />
<ResourceDictionary Source="/Controls/CopyButton.xaml" />
<ResourceDictionary Source="/Controls/Shimmer.xaml" />
<ResourceDictionary Source="/Controls/OpacityMask.xaml" />
<ResourceDictionary Source="/Controls/HomePage/Header/HeaderTile/HeaderTile.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/SemanticComboBox.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/SmartPasteForm.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/SmartTextBox.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/Controls/SemanticComboBox.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/Controls/SmartPasteForm.xaml" />
<ResourceDictionary Source="/Samples/SharedCode/Controls/SmartTextBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->

Expand Down
Binary file added AIDevGallery/Assets/Enhance.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4892f01

Please sign in to comment.