diff --git a/cmake/winml_unittests.cmake b/cmake/winml_unittests.cmake index 95661e85d8bc2..4bdbb34432466 100644 --- a/cmake/winml_unittests.cmake +++ b/cmake/winml_unittests.cmake @@ -69,6 +69,7 @@ add_winml_test( SOURCES ${winml_test_api_src} LIBS winml_test_common ) +target_compile_definitions(winml_test_api PRIVATE BUILD_GOOGLE_TEST) target_precompiled_header(winml_test_api testPch.h) if (onnxruntime_USE_DML) diff --git a/winml/test/api/APITest.h b/winml/test/api/APITest.h index 68e68f724ddf5..fd40a19b787f4 100644 --- a/winml/test/api/APITest.h +++ b/winml/test/api/APITest.h @@ -5,37 +5,25 @@ //----------------------------------------------------------------------------- #pragma once +#include "fileHelpers.h" +namespace APITest { +static void LoadModel(const std::wstring& modelPath, + winrt::Windows::AI::MachineLearning::LearningModel& learningModel) { + std::wstring fullPath = FileHelpers::GetModulePath() + modelPath; + learningModel = winrt::Windows::AI::MachineLearning::LearningModel::LoadFromFilePath(fullPath); +}; -#include - -class APITest : public ::testing::Test -{ -protected: - void LoadModel(const std::wstring& modelPath) - { - std::wstring fullPath = FileHelpers::GetModulePath() + modelPath; - m_model = winrt::Windows::AI::MachineLearning::LearningModel::LoadFromFilePath(fullPath); - } - - winrt::Windows::AI::MachineLearning::LearningModel m_model = nullptr; - winrt::Windows::AI::MachineLearning::LearningModelDevice m_device = nullptr; - winrt::Windows::AI::MachineLearning::LearningModelSession m_session = nullptr; - - uint64_t GetAdapterIdQuadPart() - { - LARGE_INTEGER id; - id.LowPart = m_device.AdapterId().LowPart; - id.HighPart = m_device.AdapterId().HighPart; - return id.QuadPart; - }; - - _LUID GetAdapterIdAsLUID() - { - _LUID id; - id.LowPart = m_device.AdapterId().LowPart; - id.HighPart = m_device.AdapterId().HighPart; - return id; - } - - bool m_runGPUTests = true; +static uint64_t GetAdapterIdQuadPart(winrt::Windows::AI::MachineLearning::LearningModelDevice& device) { + LARGE_INTEGER id; + id.LowPart = device.AdapterId().LowPart; + id.HighPart = device.AdapterId().HighPart; + return id.QuadPart; }; + +static _LUID GetAdapterIdAsLUID(winrt::Windows::AI::MachineLearning::LearningModelDevice& device) { + _LUID id; + id.LowPart = device.AdapterId().LowPart; + id.HighPart = device.AdapterId().HighPart; + return id; +} +}; // namespace APITest diff --git a/winml/test/api/LearningModelAPITest.cpp b/winml/test/api/LearningModelAPITest.cpp index ad592a9a86301..639940551d580 100644 --- a/winml/test/api/LearningModelAPITest.cpp +++ b/winml/test/api/LearningModelAPITest.cpp @@ -1,7 +1,6 @@ #include "testPch.h" - +#include "LearningModelAPITest.h" #include "APITest.h" - #include #include #include @@ -15,107 +14,96 @@ using namespace winrt::Windows::Media; using namespace winrt::Windows::Storage; using namespace winrt::Windows::Storage::Streams; -class LearningModelAPITest : public APITest -{ -protected: - LearningModelAPITest() { - init_apartment(); - m_model = nullptr; - m_device = nullptr; - m_session = nullptr; - } -}; - -class LearningModelAPITestGpu : public LearningModelAPITest -{ -protected: - void SetUp() override - { - GPUTEST - } -}; +static void LearningModelAPITestSetup() { + init_apartment(); +} -TEST_F(LearningModelAPITest, CreateModelFromFilePath) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); +static void LearningModelAPITestGpuSetup() { + GPUTEST; + init_apartment(); } -TEST_F(LearningModelAPITest, CreateModelFromIStorage) -{ - std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx"; - auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromStorageFileAsync(storageFile).get()); - EXPECT_TRUE(m_model != nullptr); - - // check the author so we know the model was populated correctly. - std::wstring author(m_model.Author()); - EXPECT_EQ(L"onnx-caffe2", author); +static void CreateModelFromFilePath() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); } -TEST_F(LearningModelAPITest, CreateModelFromIStorageOutsideCwd) -{ - std::wstring path = FileHelpers::GetModulePath() + L"ModelSubdirectory\\ModelInSubdirectory.onnx"; - auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromStorageFileAsync(storageFile).get()); - EXPECT_TRUE(m_model != nullptr); - - // check the author so we know the model was populated correctly. - std::wstring author(m_model.Author()); - EXPECT_EQ(L"onnx-caffe2", author); +static void CreateModelFromIStorage() { + std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx"; + auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStorageFileAsync(storageFile).get()); + WINML_EXPECT_TRUE(learningModel != nullptr); + + // check the author so we know the model was populated correctly. + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); } -TEST_F(LearningModelAPITest, CreateModelFromIStream) -{ - std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx"; - auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); - winrt::Windows::Storage::Streams::IRandomAccessStreamReference streamref; - storageFile.as(streamref); +static void CreateModelFromIStorageOutsideCwd() { + std::wstring path = FileHelpers::GetModulePath() + L"ModelSubdirectory\\ModelInSubdirectory.onnx"; + auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStorageFileAsync(storageFile).get()); + WINML_EXPECT_TRUE(learningModel != nullptr); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromStreamAsync(streamref).get()); - EXPECT_TRUE(m_model != nullptr); + // check the author so we know the model was populated correctly. + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); +} - // check the author so we know the model was populated correctly. - std::wstring author(m_model.Author()); - EXPECT_EQ(L"onnx-caffe2", author); +static void CreateModelFromIStream() { + std::wstring path = FileHelpers::GetModulePath() + L"squeezenet_modifiedforruntimestests.onnx"; + auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); + winrt::Windows::Storage::Streams::IRandomAccessStreamReference streamref; + storageFile.as(streamref); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStreamAsync(streamref).get()); + WINML_EXPECT_TRUE(learningModel != nullptr); + + // check the author so we know the model was populated correctly. + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); } -TEST_F(LearningModelAPITest, GetAuthor) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - std::wstring author(m_model.Author()); - EXPECT_EQ(L"onnx-caffe2", author); +static void ModelGetAuthor() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); } -TEST_F(LearningModelAPITest, GetName) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - std::wstring name(m_model.Name()); - EXPECT_EQ(L"squeezenet_old", name); +static void ModelGetName() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + std::wstring name(learningModel.Name()); + WINML_EXPECT_EQUAL(L"squeezenet_old", name); } -TEST_F(LearningModelAPITest, GetDomain) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - std::wstring domain(m_model.Domain()); - EXPECT_EQ(L"test-domain", domain); +static void ModelGetDomain() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + std::wstring domain(learningModel.Domain()); + WINML_EXPECT_EQUAL(L"test-domain", domain); } -TEST_F(LearningModelAPITest, GetDescription) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - std::wstring description(m_model.Description()); - EXPECT_EQ(L"test-doc_string", description); +static void ModelGetDescription() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + std::wstring description(learningModel.Description()); + WINML_EXPECT_EQUAL(L"test-doc_string", description); } -TEST_F(LearningModelAPITest, GetVersion) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - int64_t version(m_model.Version()); - (void)(version); +static void ModelGetVersion() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + int64_t version(learningModel.Version()); + (void)(version); } typedef std::vector> Metadata; +/* class MetadataTest : public LearningModelAPITest, public testing::WithParamInterface> {}; @@ -125,16 +113,16 @@ TEST_P(MetadataTest, GetMetaData) std::vector> keyValuePairs; tie(fileName, keyValuePairs) = GetParam(); - EXPECT_NO_THROW(LoadModel(fileName.c_str())); - EXPECT_TRUE(m_model.Metadata() != nullptr); - EXPECT_EQ(keyValuePairs.size(), m_model.Metadata().Size()); + WINML_EXPECT_NO_THROW(LoadModel(fileName.c_str())); + WINML_EXPECT_TRUE(m_model.Metadata() != nullptr); + WINML_EXPECT_EQUAL(keyValuePairs.size(), m_model.Metadata().Size()); auto iter = m_model.Metadata().First(); for (auto& keyValue : keyValuePairs) { - EXPECT_TRUE(iter.HasCurrent()); - EXPECT_EQ(keyValue.first, std::wstring(iter.Current().Key())); - EXPECT_EQ(keyValue.second, std::wstring(iter.Current().Value())); + WINML_EXPECT_TRUE(iter.HasCurrent()); + WINML_EXPECT_EQUAL(keyValue.first, std::wstring(iter.Current().Key())); + WINML_EXPECT_EQUAL(keyValue.second, std::wstring(iter.Current().Value())); iter.MoveNext(); } } @@ -147,122 +135,141 @@ INSTANTIATE_TEST_SUITE_P( std::pair(L"modelWithMetaData.onnx", Metadata{{L"thisisalongkey", L"thisisalongvalue"}}), std::pair(L"modelWith2MetaData.onnx", Metadata{{L"thisisalongkey", L"thisisalongvalue"}, {L"key2", L"val2"}}) )); +*/ -TEST_F(LearningModelAPITest, EnumerateInputs) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); +static void EnumerateInputs() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); - // purposely don't cache "InputFeatures" in order to exercise calling it multiple times - EXPECT_TRUE(m_model.InputFeatures().First().HasCurrent()); + // purposely don't cache "InputFeatures" in order to exercise calling it multiple times + WINML_EXPECT_TRUE(learningModel.InputFeatures().First().HasCurrent()); - std::wstring name(m_model.InputFeatures().First().Current().Name()); - EXPECT_EQ(L"data_0", name); + std::wstring name(learningModel.InputFeatures().First().Current().Name()); + WINML_EXPECT_EQUAL(L"data_0", name); - // make sure it's either tensor or image - TensorFeatureDescriptor tensorDescriptor = nullptr; - m_model.InputFeatures().First().Current().try_as(tensorDescriptor); - if (tensorDescriptor == nullptr) - { - ImageFeatureDescriptor imageDescriptor = nullptr; - EXPECT_NO_THROW(m_model.InputFeatures().First().Current().as(imageDescriptor)); - } + // make sure it's either tensor or image + TensorFeatureDescriptor tensorDescriptor = nullptr; + learningModel.InputFeatures().First().Current().try_as(tensorDescriptor); + if (tensorDescriptor == nullptr) { + ImageFeatureDescriptor imageDescriptor = nullptr; + WINML_EXPECT_NO_THROW(learningModel.InputFeatures().First().Current().as(imageDescriptor)); + } - auto modelDataKind = tensorDescriptor.TensorKind(); - EXPECT_EQ(TensorKind::Float, modelDataKind); + auto modelDataKind = tensorDescriptor.TensorKind(); + WINML_EXPECT_EQUAL(TensorKind::Float, modelDataKind); - EXPECT_TRUE(tensorDescriptor.IsRequired()); + WINML_EXPECT_TRUE(tensorDescriptor.IsRequired()); - std::vector expectedShapes = { 1,3,224,224 }; - EXPECT_EQ(expectedShapes.size(), tensorDescriptor.Shape().Size()); - for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) - { - EXPECT_EQ(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j)); - } + std::vector expectedShapes = {1, 3, 224, 224}; + WINML_EXPECT_EQUAL(expectedShapes.size(), tensorDescriptor.Shape().Size()); + for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) { + WINML_EXPECT_EQUAL(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j)); + } - auto first = m_model.InputFeatures().First(); - first.MoveNext(); - EXPECT_FALSE(first.HasCurrent()); + auto first = learningModel.InputFeatures().First(); + first.MoveNext(); + WINML_EXPECT_FALSE(first.HasCurrent()); } -TEST_F(LearningModelAPITest, EnumerateOutputs) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); +static void EnumerateOutputs() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); - // purposely don't cache "OutputFeatures" in order to exercise calling it multiple times - std::wstring name(m_model.OutputFeatures().First().Current().Name()); - EXPECT_EQ(L"softmaxout_1", name); + // purposely don't cache "OutputFeatures" in order to exercise calling it multiple times + std::wstring name(learningModel.OutputFeatures().First().Current().Name()); + WINML_EXPECT_EQUAL(L"softmaxout_1", name); - TensorFeatureDescriptor tensorDescriptor = nullptr; - EXPECT_NO_THROW(m_model.OutputFeatures().First().Current().as(tensorDescriptor)); - EXPECT_TRUE(tensorDescriptor != nullptr); + TensorFeatureDescriptor tensorDescriptor = nullptr; + WINML_EXPECT_NO_THROW(learningModel.OutputFeatures().First().Current().as(tensorDescriptor)); + WINML_EXPECT_TRUE(tensorDescriptor != nullptr); - auto tensorName = tensorDescriptor.Name(); - EXPECT_EQ(L"softmaxout_1", tensorName); + auto tensorName = tensorDescriptor.Name(); + WINML_EXPECT_EQUAL(L"softmaxout_1", tensorName); - auto modelDataKind = tensorDescriptor.TensorKind(); - EXPECT_EQ(TensorKind::Float, modelDataKind); + auto modelDataKind = tensorDescriptor.TensorKind(); + WINML_EXPECT_EQUAL(TensorKind::Float, modelDataKind); - EXPECT_TRUE(tensorDescriptor.IsRequired()); + WINML_EXPECT_TRUE(tensorDescriptor.IsRequired()); - std::vector expectedShapes = { 1, 1000, 1, 1 }; - EXPECT_EQ(expectedShapes.size(), tensorDescriptor.Shape().Size()); - for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) - { - EXPECT_EQ(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j)); - } + std::vector expectedShapes = {1, 1000, 1, 1}; + WINML_EXPECT_EQUAL(expectedShapes.size(), tensorDescriptor.Shape().Size()); + for (uint32_t j = 0; j < tensorDescriptor.Shape().Size(); j++) { + WINML_EXPECT_EQUAL(expectedShapes.at(j), tensorDescriptor.Shape().GetAt(j)); + } - auto first = m_model.OutputFeatures().First(); - first.MoveNext(); - EXPECT_FALSE(first.HasCurrent()); + auto first = learningModel.OutputFeatures().First(); + first.MoveNext(); + WINML_EXPECT_FALSE(first.HasCurrent()); } -TEST_F(LearningModelAPITest, CloseModelCheckMetadata) -{ - EXPECT_NO_THROW(LoadModel(L"squeezenet_modifiedforruntimestests.onnx")); - EXPECT_NO_THROW(m_model.Close()); - std::wstring author(m_model.Author()); - EXPECT_EQ(L"onnx-caffe2", author); - std::wstring name(m_model.Name()); - EXPECT_EQ(L"squeezenet_old", name); - std::wstring domain(m_model.Domain()); - EXPECT_EQ(L"test-domain", domain); - std::wstring description(m_model.Description()); - EXPECT_EQ(L"test-doc_string", description); - int64_t version(m_model.Version()); - EXPECT_EQ(123456, version); +static void CloseModelCheckMetadata() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"squeezenet_modifiedforruntimestests.onnx", learningModel)); + WINML_EXPECT_NO_THROW(learningModel.Close()); + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(L"onnx-caffe2", author); + std::wstring name(learningModel.Name()); + WINML_EXPECT_EQUAL(L"squeezenet_old", name); + std::wstring domain(learningModel.Domain()); + WINML_EXPECT_EQUAL(L"test-domain", domain); + std::wstring description(learningModel.Description()); + WINML_EXPECT_EQUAL(L"test-doc_string", description); + int64_t version(learningModel.Version()); + WINML_EXPECT_EQUAL(123456, version); } -TEST_F(LearningModelAPITestGpu, CloseModelCheckEval) -{ - EXPECT_NO_THROW(LoadModel(L"model.onnx")); - LearningModelSession session = nullptr; - EXPECT_NO_THROW(session = LearningModelSession(m_model)); - EXPECT_NO_THROW(m_model.Close()); - - std::wstring fullImagePath = FileHelpers::GetModulePath() + L"kitten_224.png"; - StorageFile imagefile = StorageFile::GetFileFromPathAsync(fullImagePath).get(); - IRandomAccessStream stream = imagefile.OpenAsync(FileAccessMode::Read).get(); - SoftwareBitmap softwareBitmap = (BitmapDecoder::CreateAsync(stream).get()).GetSoftwareBitmapAsync().get(); - VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap); - - LearningModelBinding binding = nullptr; - EXPECT_NO_THROW(binding = LearningModelBinding(session)); - EXPECT_NO_THROW(binding.Bind(m_model.InputFeatures().First().Current().Name(), frame)); - - EXPECT_NO_THROW(session.Evaluate(binding, L"")); +static void CloseModelCheckEval() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); + LearningModelSession session = nullptr; + WINML_EXPECT_NO_THROW(session = LearningModelSession(learningModel)); + WINML_EXPECT_NO_THROW(learningModel.Close()); + + std::wstring fullImagePath = FileHelpers::GetModulePath() + L"kitten_224.png"; + StorageFile imagefile = StorageFile::GetFileFromPathAsync(fullImagePath).get(); + IRandomAccessStream stream = imagefile.OpenAsync(FileAccessMode::Read).get(); + SoftwareBitmap softwareBitmap = (BitmapDecoder::CreateAsync(stream).get()).GetSoftwareBitmapAsync().get(); + VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap); + + LearningModelBinding binding = nullptr; + WINML_EXPECT_NO_THROW(binding = LearningModelBinding(session)); + WINML_EXPECT_NO_THROW(binding.Bind(learningModel.InputFeatures().First().Current().Name(), frame)); + + WINML_EXPECT_NO_THROW(session.Evaluate(binding, L"")); } -TEST_F(LearningModelAPITest, CloseModelNoNewSessions) -{ - EXPECT_NO_THROW(LoadModel(L"model.onnx")); - EXPECT_NO_THROW(m_model.Close()); - LearningModelSession session = nullptr; - EXPECT_THROW( - try { - session = LearningModelSession(m_model); - } catch (const winrt::hresult_error& e) { - EXPECT_EQ(E_INVALIDARG, e.code()); - throw; - } - , winrt::hresult_error); +static void CloseModelNoNewSessions() { + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); + WINML_EXPECT_NO_THROW(learningModel.Close()); + LearningModelSession session = nullptr; + WINML_EXPECT_THROW_SPECIFIC( + session = LearningModelSession(learningModel);, + winrt::hresult_error, + [](const winrt::hresult_error& e) -> bool { + return e.code() == E_INVALIDARG; + }); } + +const LearningModelApiTestApi& getapi() { + static constexpr LearningModelApiTestApi api = + { + LearningModelAPITestSetup, + LearningModelAPITestGpuSetup, + CreateModelFromFilePath, + CreateModelFromIStorage, + CreateModelFromIStorageOutsideCwd, + CreateModelFromIStream, + ModelGetAuthor, + ModelGetName, + ModelGetDomain, + ModelGetDescription, + ModelGetVersion, + EnumerateInputs, + EnumerateOutputs, + CloseModelCheckMetadata, + CloseModelCheckEval, + CloseModelNoNewSessions + }; + return api; +} \ No newline at end of file diff --git a/winml/test/api/LearningModelAPITest.h b/winml/test/api/LearningModelAPITest.h new file mode 100644 index 0000000000000..4a723ab2d9d29 --- /dev/null +++ b/winml/test/api/LearningModelAPITest.h @@ -0,0 +1,41 @@ +#include "test.h" +struct LearningModelApiTestApi +{ + SetupTest LearningModelAPITestSetup; + SetupTest LearningModelAPITestGpuSetup; + VoidTest CreateModelFromFilePath; + VoidTest CreateModelFromIStorage; + VoidTest CreateModelFromIStorageOutsideCwd; + VoidTest CreateModelFromIStream; + VoidTest ModelGetAuthor; + VoidTest ModelGetName; + VoidTest ModelGetDomain; + VoidTest ModelGetDescription; + VoidTest ModelGetVersion; + VoidTest EnumerateInputs; + VoidTest EnumerateOutputs; + VoidTest CloseModelCheckMetadata; + VoidTest CloseModelCheckEval; + VoidTest CloseModelNoNewSessions; +}; +const LearningModelApiTestApi& getapi(); + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelAPITest, LearningModelAPITestSetup) +WINML_TEST(LearningModelAPITest, CreateModelFromFilePath) +WINML_TEST(LearningModelAPITest, CreateModelFromIStorage) +WINML_TEST(LearningModelAPITest, CreateModelFromIStorageOutsideCwd) +WINML_TEST(LearningModelAPITest, CreateModelFromIStream) +WINML_TEST(LearningModelAPITest, ModelGetAuthor) +WINML_TEST(LearningModelAPITest, ModelGetName) +WINML_TEST(LearningModelAPITest, ModelGetDomain) +WINML_TEST(LearningModelAPITest, ModelGetDescription) +WINML_TEST(LearningModelAPITest, ModelGetVersion) +WINML_TEST(LearningModelAPITest, EnumerateInputs) +WINML_TEST(LearningModelAPITest, EnumerateOutputs) +WINML_TEST(LearningModelAPITest, CloseModelCheckMetadata) +WINML_TEST(LearningModelAPITest, CloseModelNoNewSessions) +WINML_TEST_CLASS_END() + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelAPITestGpu, LearningModelAPITestGpuSetup) +WINML_TEST(LearningModelAPITestGpu, CloseModelCheckEval) +WINML_TEST_CLASS_END() \ No newline at end of file diff --git a/winml/test/api/LearningModelBindingAPITest.cpp b/winml/test/api/LearningModelBindingAPITest.cpp index 969c28ba63937..99d9dc6e9b251 100644 --- a/winml/test/api/LearningModelBindingAPITest.cpp +++ b/winml/test/api/LearningModelBindingAPITest.cpp @@ -1,13 +1,14 @@ #include "testPch.h" #include "APITest.h" +#include "LearningModelBindingAPITest.h" #include "SqueezeNetValidator.h" #include #include #include "winrt/Windows.Storage.h" #include "DeviceHelpers.h" - +#include using namespace winrt; using namespace winrt::Windows::AI::MachineLearning; using namespace winrt::Windows::Foundation::Collections; @@ -15,25 +16,22 @@ using namespace winrt::Windows::Graphics::Imaging; using namespace winrt::Windows::Media; using namespace winrt::Windows::Storage; -class LearningModelBindingAPITest : public APITest -{}; +static void LearningModelBindingAPITestSetup() { + init_apartment(); +} -class LearningModelBindingAPITestGpu : public LearningModelBindingAPITest -{ -protected: - void SetUp() override - { - GPUTEST - } -}; +static void LearningModelBindingAPITestGpuSetup() { + GPUTEST; + init_apartment(); +} -TEST_F(LearningModelBindingAPITest, CpuSqueezeNet) +static void CpuSqueezeNet() { std::string cpuInstance("CPU"); WinML::Engine::Test::ModelValidator::SqueezeNet(cpuInstance, LearningModelDeviceKind::Cpu, /*dataTolerance*/ 0.00001f, false); } -TEST_F(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs) +static void CpuSqueezeNetEmptyOutputs() { std::string cpuInstance("CPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -44,7 +42,7 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs) OutputBindingStrategy::Empty); } -TEST_F(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs) +static void CpuSqueezeNetUnboundOutputs() { std::string cpuInstance("CPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -55,7 +53,7 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs) OutputBindingStrategy::Unbound); } -TEST_F(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable) +static void CpuSqueezeNetBindInputTensorAsInspectable() { std::string cpuInstance("CPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -67,27 +65,28 @@ TEST_F(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable) true /* bind inputs as inspectables */); } -TEST_F(LearningModelBindingAPITest, CastMapInt64) +static void CastMapInt64() { - EXPECT_NO_THROW(LoadModel(L"castmap-int64.onnx")); + WINML_EXPECT_NO_THROW(LearningModel::LoadFromFilePath(FileHelpers::GetModulePath() + L"castmap-int64.onnx")); // TODO: Check Descriptor } -TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapInt64) +static void DictionaryVectorizerMapInt64() { - EXPECT_NO_THROW(LoadModel(L"dictvectorizer-int64.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-int64.onnx", learningModel)); - auto inputDescriptor = m_model.InputFeatures().First().Current(); - EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map); + auto inputDescriptor = learningModel.InputFeatures().First().Current(); + WINML_EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map); auto mapDescriptor = inputDescriptor.as(); - EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64); - EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); + WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64); + WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); auto tensorDescriptor = mapDescriptor.ValueDescriptor().as(); // empty size means tensor of scalar value - EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0); - EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); + WINML_EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0); + WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); - LearningModelSession modelSession(m_model); + LearningModelSession modelSession(learningModel); LearningModelBinding binding(modelSession); std::unordered_map map; map[1] = 1.f; @@ -102,38 +101,39 @@ TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapInt64) binding.Bind(mapInputName, abiMap); auto mapInputInspectable = abiMap.as(); auto first = binding.First(); - EXPECT_TRUE(first.Current().Key() == mapInputName); - EXPECT_TRUE(first.Current().Value() == mapInputInspectable); - EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable); + WINML_EXPECT_TRUE(first.Current().Key() == mapInputName); + WINML_EXPECT_TRUE(first.Current().Value() == mapInputInspectable); + WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable); // Bind as IMapView auto mapView = abiMap.GetView(); binding.Bind(mapInputName, mapView); mapInputInspectable = mapView.as(); first = binding.First(); - EXPECT_TRUE(first.Current().Key() == mapInputName); - EXPECT_TRUE(first.Current().Value() == mapView); - EXPECT_TRUE(binding.Lookup(mapInputName) == mapView); + WINML_EXPECT_TRUE(first.Current().Key() == mapInputName); + WINML_EXPECT_TRUE(first.Current().Value() == mapView); + WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapView); } -TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapString) +static void DictionaryVectorizerMapString() { - EXPECT_NO_THROW(LoadModel(L"dictvectorizer-string.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-string.onnx", learningModel)); - auto inputDescriptor = m_model.InputFeatures().First().Current(); - EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map); + auto inputDescriptor = learningModel.InputFeatures().First().Current(); + WINML_EXPECT_TRUE(inputDescriptor.Kind() == LearningModelFeatureKind::Map); auto mapDescriptor = inputDescriptor.as(); - EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String); - EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); + WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String); + WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); auto tensorDescriptor = mapDescriptor.ValueDescriptor().as(); // empty size means tensor of scalar value - EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0); - EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); + WINML_EXPECT_TRUE(tensorDescriptor.Shape().Size() == 0); + WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); - LearningModelSession modelSession(m_model); + LearningModelSession modelSession(learningModel); LearningModelBinding binding(modelSession); std::unordered_map map; map[L"1"] = 1.f; @@ -146,9 +146,9 @@ TEST_F(LearningModelBindingAPITest, DictionaryVectorizerMapString) auto mapInputInspectable = abiMap.as(); auto first = binding.First(); - EXPECT_TRUE(first.Current().Key() == mapInputName); - EXPECT_TRUE(first.Current().Value() == mapInputInspectable); - EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable); + WINML_EXPECT_TRUE(first.Current().Key() == mapInputName); + WINML_EXPECT_TRUE(first.Current().Value() == mapInputInspectable); + WINML_EXPECT_TRUE(binding.Lookup(mapInputName) == mapInputInspectable); } static void RunZipMapInt64( @@ -157,15 +157,15 @@ static void RunZipMapInt64( { auto outputFeatures = model.OutputFeatures(); auto outputDescriptor = outputFeatures.First().Current(); - EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence); + WINML_EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence); auto seqDescriptor = outputDescriptor.as(); auto mapDescriptor = seqDescriptor.ElementDescriptor().as(); - EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64); + WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::Int64); - EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); + WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); auto tensorDescriptor = mapDescriptor.ValueDescriptor().as(); - EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); + WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); LearningModelSession session(model); LearningModelBinding binding(session); @@ -199,63 +199,66 @@ static void RunZipMapInt64( // from output binding const auto &out1 = abiOutput.GetAt(0); const auto &out2 = result.Lookup(L"Y").as>().GetAt(0); - SCOPED_TRACE((std::ostringstream() << "size: " << out1.Size()).str()); + WINML_LOG_COMMENT((std::ostringstream() << "size: " << out1.Size()).str()); // check outputs auto iter1 = out1.First(); auto iter2 = out2.First(); for (uint32_t i = 0, size = (uint32_t)inputs.size(); i < size; ++i) { - EXPECT_TRUE(iter1.HasCurrent()); - EXPECT_TRUE(iter2.HasCurrent()); + WINML_EXPECT_TRUE(iter1.HasCurrent()); + WINML_EXPECT_TRUE(iter2.HasCurrent()); const auto &pair1 = iter1.Current(); const auto &pair2 = iter2.Current(); - SCOPED_TRACE((std::ostringstream() << "key: " << pair1.Key() << ", value: " << pair2.Value()).str()); - EXPECT_TRUE(pair1.Key() == i && pair2.Key() == i); - EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]); + WINML_LOG_COMMENT((std::ostringstream() << "key: " << pair1.Key() << ", value: " << pair2.Value()).str()); + WINML_EXPECT_TRUE(pair1.Key() == i && pair2.Key() == i); + WINML_EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]); iter1.MoveNext(); iter2.MoveNext(); } - EXPECT_TRUE(!iter1.HasCurrent()); - EXPECT_TRUE(!iter2.HasCurrent()); + WINML_EXPECT_TRUE(!iter1.HasCurrent()); + WINML_EXPECT_TRUE(!iter2.HasCurrent()); } else { abiOutput = result.Lookup(L"Y").as(); - EXPECT_TRUE(abiOutput.Size() == 1); + WINML_EXPECT_TRUE(abiOutput.Size() == 1); ABIMap map = abiOutput.GetAt(0); - EXPECT_TRUE(map.Size() == 3); - EXPECT_TRUE(map.Lookup(0) == 0.5); - EXPECT_TRUE(map.Lookup(1) == .25); - EXPECT_TRUE(map.Lookup(2) == .125); + WINML_EXPECT_TRUE(map.Size() == 3); + WINML_EXPECT_TRUE(map.Lookup(0) == 0.5); + WINML_EXPECT_TRUE(map.Lookup(1) == .25); + WINML_EXPECT_TRUE(map.Lookup(2) == .125); } } -TEST_F(LearningModelBindingAPITest, ZipMapInt64) +static void ZipMapInt64() { - EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx")); - RunZipMapInt64(m_model, OutputBindingStrategy::Bound); + LearningModel learningModel= nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel)); + RunZipMapInt64(learningModel, OutputBindingStrategy::Bound); } -TEST_F(LearningModelBindingAPITest, ZipMapInt64Unbound) +static void ZipMapInt64Unbound() { - EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx")); - RunZipMapInt64(m_model, OutputBindingStrategy::Unbound); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel)); + RunZipMapInt64(learningModel, OutputBindingStrategy::Unbound); } -TEST_F(LearningModelBindingAPITest, ZipMapString) +static void ZipMapString() { // output constraint: "seq(map(string, float))" or "seq(map(int64, float))" - EXPECT_NO_THROW(LoadModel(L"zipmap-string.onnx")); - auto outputs = m_model.OutputFeatures(); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-string.onnx", learningModel)); + auto outputs = learningModel.OutputFeatures(); auto outputDescriptor = outputs.First().Current(); - EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence); + WINML_EXPECT_TRUE(outputDescriptor.Kind() == LearningModelFeatureKind::Sequence); auto mapDescriptor = outputDescriptor.as().ElementDescriptor().as(); - EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String); - EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); + WINML_EXPECT_TRUE(mapDescriptor.KeyKind() == TensorKind::String); + WINML_EXPECT_TRUE(mapDescriptor.ValueDescriptor().Kind() == LearningModelFeatureKind::Tensor); auto tensorDescriptor = mapDescriptor.ValueDescriptor().as(); - EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); + WINML_EXPECT_TRUE(tensorDescriptor.TensorKind() == TensorKind::Float); - LearningModelSession session(m_model); + LearningModelSession session(learningModel); LearningModelBinding binding(session); std::vector inputs = { 0.5f, 0.25f, 0.125f }; @@ -274,27 +277,27 @@ TEST_F(LearningModelBindingAPITest, ZipMapString) // from output binding const auto &out1 = ABIOutput.GetAt(0); const auto &out2 = result.Lookup(L"Y").as>().GetAt(0); - SCOPED_TRACE((std::ostringstream() << "size: " << out1.Size()).str()); + WINML_LOG_COMMENT((std::ostringstream() << "size: " << out1.Size()).str()); // single key,value pair for each map auto iter1 = out1.First(); auto iter2 = out2.First(); for (uint32_t i = 0, size = (uint32_t)inputs.size(); i < size; ++i) { - EXPECT_TRUE(iter2.HasCurrent()); + WINML_EXPECT_TRUE(iter2.HasCurrent()); const auto &pair1 = iter1.Current(); const auto &pair2 = iter2.Current(); - SCOPED_TRACE((std::ostringstream() << "key: " << pair1.Key().c_str() << ", value " << pair2.Value()).str()); - EXPECT_TRUE(std::wstring(pair1.Key().c_str()).compare(labels[i]) == 0); - EXPECT_TRUE(std::wstring(pair2.Key().c_str()).compare(labels[i]) == 0); - EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]); + WINML_LOG_COMMENT((std::ostringstream() << "key: " << pair1.Key().c_str() << ", value " << pair2.Value()).str()); + WINML_EXPECT_TRUE(std::wstring(pair1.Key().c_str()).compare(labels[i]) == 0); + WINML_EXPECT_TRUE(std::wstring(pair2.Key().c_str()).compare(labels[i]) == 0); + WINML_EXPECT_TRUE(pair1.Value() == inputs[i] && pair2.Value() == inputs[i]); iter1.MoveNext(); iter2.MoveNext(); } - EXPECT_TRUE(!iter1.HasCurrent()); - EXPECT_TRUE(!iter2.HasCurrent()); + WINML_EXPECT_TRUE(!iter1.HasCurrent()); + WINML_EXPECT_TRUE(!iter2.HasCurrent()); } -TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNet) +static void GpuSqueezeNet() { std::string gpuInstance("GPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -303,7 +306,7 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNet) /*dataTolerance*/ 0.00001f); } -TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs) +static void GpuSqueezeNetEmptyOutputs() { std::string gpuInstance("GPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -314,7 +317,7 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs) OutputBindingStrategy::Empty); } -TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs) +static void GpuSqueezeNetUnboundOutputs() { std::string gpuInstance("GPU"); WinML::Engine::Test::ModelValidator::SqueezeNet( @@ -326,44 +329,48 @@ TEST_F(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs) } // Validates that when the input image is the same as the model expects, the binding step is executed correctly. -TEST_F(LearningModelBindingAPITestGpu, ImageBindingDimensions) +static void ImageBindingDimensions() { - LearningModelBinding m_binding = nullptr; + LearningModelBinding learningModelBinding = nullptr; + LearningModel learningModel = nullptr; + LearningModelSession learningModelSession = nullptr; + LearningModelDevice leraningModelDevice = nullptr; std::wstring filePath = FileHelpers::GetModulePath() + L"model.onnx"; // load a model with expected input size: 224 x 224 - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default)); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(filePath)); - EXPECT_TRUE(m_model != nullptr); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); - EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session)); + WINML_EXPECT_NO_THROW(leraningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default)); + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(filePath)); + WINML_EXPECT_TRUE(learningModel != nullptr); + WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, leraningModelDevice)); + WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession)); // Create input images and execute bind // Test Case 1: both width and height are larger than model expects VideoFrame inputImage1(BitmapPixelFormat::Rgba8, 1000, 1000); ImageFeatureValue inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage1); - EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor)); // Test Case 2: only height is larger, while width is smaller VideoFrame inputImage2(BitmapPixelFormat::Rgba8, 20, 1000); inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage2); - EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor)); // Test Case 3: only width is larger, while height is smaller VideoFrame inputImage3(BitmapPixelFormat::Rgba8, 1000, 20); inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage3); - EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor)); // Test Case 4: both width and height are smaller than model expects VideoFrame inputImage4(BitmapPixelFormat::Rgba8, 20, 20); inputTensor = ImageFeatureValue::CreateFromVideoFrame(inputImage4); - EXPECT_NO_THROW(m_binding.Bind(L"data_0", inputTensor)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"data_0", inputTensor)); } -TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions) +static void VerifyInvalidBindExceptions() { - EXPECT_NO_THROW(LoadModel(L"zipmap-int64.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"zipmap-int64.onnx", learningModel)); - LearningModelSession session(m_model); + LearningModelSession session(learningModel); LearningModelBinding binding(session); std::vector inputs = { 0.5f, 0.25f, 0.125f }; @@ -384,47 +391,47 @@ TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions) // Bind invalid image as tensorfloat input auto image = FileHelpers::LoadImageFeatureValue(L"227x227.png"); - EXPECT_THROW_SPECIFIC(binding.Bind(L"X", image), winrt::hresult_error, ensureWinmlSizeMismatch); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", image), winrt::hresult_error, ensureWinmlSizeMismatch); // Bind invalid map as tensorfloat input std::unordered_map map; auto abiMap = winrt::single_threaded_map(std::move(map)); - EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid sequence as tensorfloat input std::vector sequence; auto abiSequence = winrt::single_threaded_vector(std::move(sequence)); - EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid tensor size as tensorfloat input auto tensorBoolean = TensorBoolean::Create(); - EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid tensor shape as tensorfloat input auto tensorInvalidShape = TensorFloat::Create(std::vector { 2, 3, 4 }); - EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"X", tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding); /* Verify sequence bindings throw correct bind exceptions */ // Bind invalid image as sequence output - EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", image), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", image), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid map as sequence output - EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid sequence as sequence output - EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid tensor as sequence output - EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(binding.Bind(L"Y", tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); /* Verify image bindings throw correct bind exceptions */ - // EXPECT_NO_THROW(LoadModel(L"fns-candy.onnx")); + // WINML_EXPECT_NO_THROW(LoadModel(L"fns-candy.onnx")); // LearningModelSession imageSession(m_model); // LearningModelBinding imageBinding(imageSession); @@ -432,74 +439,77 @@ TEST_F(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions) // auto inputName = m_model.InputFeatures().First().Current().Name(); // // Bind invalid map as image input - // EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); + // WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); // // Bind invalid sequence as image input - // EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); + // WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); // // Bind invalid tensor type as image input - // EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); + // WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); // // Bind invalid tensor size as image input // auto tensorFloat = TensorFloat::Create(std::vector { 1, 1, 100, 100 }); - // EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorFloat), winrt::hresult_error, ensureWinmlInvalidBinding); + // WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorFloat), winrt::hresult_error, ensureWinmlInvalidBinding); // // Bind invalid tensor shape as image input - // EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding); + // WINML_EXPECT_THROW_SPECIFIC(imageBinding.Bind(inputName, tensorInvalidShape), winrt::hresult_error, ensureWinmlInvalidBinding); /* Verify map bindings throw correct bind exceptions */ - EXPECT_NO_THROW(LoadModel(L"dictvectorizer-int64.onnx")); + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"dictvectorizer-int64.onnx", learningModel)); - LearningModelSession mapSession(m_model); + LearningModelSession mapSession(learningModel); LearningModelBinding mapBinding(mapSession); - auto inputName = m_model.InputFeatures().First().Current().Name(); + auto inputName = learningModel.InputFeatures().First().Current().Name(); // Bind invalid image as image input auto smallImage = FileHelpers::LoadImageFeatureValue(L"100x100.png"); - EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, smallImage), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, smallImage), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid map as image input - EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiMap), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid sequence as image input - EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, abiSequence), winrt::hresult_error, ensureWinmlInvalidBinding); // Bind invalid tensor type as image input - EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); + WINML_EXPECT_THROW_SPECIFIC(mapBinding.Bind(inputName, tensorBoolean), winrt::hresult_error, ensureWinmlInvalidBinding); } // Verify that it throws an error when binding an invalid name. -TEST_F(LearningModelBindingAPITestGpu, BindInvalidInputName) +static void BindInvalidInputName() { - LearningModelBinding m_binding = nullptr; + LearningModel learningModel = nullptr; + LearningModelBinding learningModelBinding = nullptr; + LearningModelDevice learningModelDevice = nullptr; + LearningModelSession learningModelSession = nullptr; std::wstring modelPath = FileHelpers::GetModulePath() + L"Add_ImageNet1920.onnx"; - EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(modelPath)); - EXPECT_TRUE(m_model != nullptr); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); - EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session)); + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(modelPath)); + WINML_EXPECT_TRUE(learningModel != nullptr); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default)); + WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice)); + WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession)); VideoFrame iuputImage(BitmapPixelFormat::Rgba8, 1920, 1080); ImageFeatureValue inputTensor = ImageFeatureValue::CreateFromVideoFrame(iuputImage); - auto first = m_model.InputFeatures().First(); + auto first = learningModel.InputFeatures().First(); std::wstring testInvalidName = L"0"; // Verify that testInvalidName is not in model's InputFeatures while (first.HasCurrent()) { - EXPECT_NE(testInvalidName, first.Current().Name()); + WINML_EXPECT_NOT_EQUAL(testInvalidName, first.Current().Name()); first.MoveNext(); } // Bind inputTensor to a valid input name - EXPECT_NO_THROW(m_binding.Bind(L"input_39:0", inputTensor)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"input_39:0", inputTensor)); // Bind inputTensor to an invalid input name - EXPECT_THROW_SPECIFIC(m_binding.Bind(testInvalidName, inputTensor), + WINML_EXPECT_THROW_SPECIFIC(learningModelBinding.Bind(testInvalidName, inputTensor), winrt::hresult_error, [](const winrt::hresult_error& e) -> bool { @@ -507,15 +517,18 @@ TEST_F(LearningModelBindingAPITestGpu, BindInvalidInputName) }); } -TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice) +static void VerifyOutputAfterEvaluateAsyncCalledTwice() { - LearningModelBinding m_binding = nullptr; + LearningModel learningModel = nullptr; + LearningModelBinding learningModelBinding = nullptr; + LearningModelDevice learningModelDevice = nullptr; + LearningModelSession learningModelSession = nullptr; std::wstring filePath = FileHelpers::GetModulePath() + L"relu.onnx"; - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default)); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromFilePath(filePath)); - EXPECT_TRUE(m_model != nullptr); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); - EXPECT_NO_THROW(m_binding = LearningModelBinding(m_session)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default)); + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromFilePath(filePath)); + WINML_EXPECT_TRUE(learningModel != nullptr); + WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice)); + WINML_EXPECT_NO_THROW(learningModelBinding = LearningModelBinding(learningModelSession)); auto inputShape = std::vector{ 5 }; auto inputData1 = std::vector{ -50.f, -25.f, 0.f, 25.f, 50.f }; @@ -530,22 +543,22 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice) inputShape, single_threaded_vector(std::move(inputData2)).GetView()); - EXPECT_NO_THROW(m_binding.Bind(L"X", inputValue1)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"X", inputValue1)); auto outputValue = TensorFloat::Create(); - EXPECT_NO_THROW(m_binding.Bind(L"Y", outputValue)); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"Y", outputValue)); - EXPECT_NO_THROW(m_session.Evaluate(m_binding, L"")); + WINML_EXPECT_NO_THROW(learningModelSession.Evaluate(learningModelBinding, L"")); auto buffer1 = outputValue.GetAsVectorView(); - EXPECT_TRUE(buffer1 != nullptr); + WINML_EXPECT_TRUE(buffer1 != nullptr); // The second evaluation // If we don't bind output again, the output value will not change - EXPECT_NO_THROW(m_binding.Bind(L"X", inputValue2)); - EXPECT_NO_THROW(m_session.Evaluate(m_binding, L"")); + WINML_EXPECT_NO_THROW(learningModelBinding.Bind(L"X", inputValue2)); + WINML_EXPECT_NO_THROW(learningModelSession.Evaluate(learningModelBinding, L"")); auto buffer2 = outputValue.GetAsVectorView(); - EXPECT_EQ(buffer1.Size(), buffer2.Size()); + WINML_EXPECT_EQUAL(buffer1.Size(), buffer2.Size()); bool isSame = true; for (uint32_t i = 0; i < buffer1.Size(); ++i) { @@ -555,7 +568,7 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice) break; } } - EXPECT_FALSE(isSame); + WINML_EXPECT_FALSE(isSame); } static VideoFrame CreateVideoFrame(const wchar_t* path) @@ -567,7 +580,7 @@ static VideoFrame CreateVideoFrame(const wchar_t* path) return VideoFrame::CreateWithSoftwareBitmap(softwareBitmap); } -TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) +static void VerifyOutputAfterImageBindCalledTwice() { std::wstring fullModelPath = FileHelpers::GetModulePath() + L"model.onnx"; std::wstring fullImagePath1 = FileHelpers::GetModulePath() + L"kitten_224.png"; @@ -575,9 +588,9 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) // winml model creation LearningModel model = nullptr; - EXPECT_NO_THROW(model = LearningModel::LoadFromFilePath(fullModelPath)); + WINML_EXPECT_NO_THROW(model = LearningModel::LoadFromFilePath(fullModelPath)); LearningModelSession modelSession = nullptr; - EXPECT_NO_THROW(modelSession = LearningModelSession(model, LearningModelDevice(LearningModelDeviceKind::Default))); + WINML_EXPECT_NO_THROW(modelSession = LearningModelSession(model, LearningModelDevice(LearningModelDeviceKind::Default))); LearningModelBinding modelBinding(modelSession); // create the tensor for the actual output @@ -587,8 +600,8 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) // Bind image 1 and evaluate auto frame = CreateVideoFrame(fullImagePath1.c_str()); auto imageTensor = ImageFeatureValue::CreateFromVideoFrame(frame); - EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor)); - EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L"")); + WINML_EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor)); + WINML_EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L"")); // Store 1st result auto outputVectorView1 = output.GetAsVectorView(); @@ -598,13 +611,13 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) // The expected result is that the videoframe will be re-tensorized at bind auto frame2 = CreateVideoFrame(fullImagePath2.c_str()); frame2.CopyToAsync(frame).get(); - EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor)); - EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L"")); + WINML_EXPECT_NO_THROW(modelBinding.Bind(L"data_0", imageTensor)); + WINML_EXPECT_NO_THROW(modelSession.Evaluate(modelBinding, L"")); // Store 2nd result auto outputVectorView2 = output.GetAsVectorView(); - EXPECT_EQ(outputVectorView1.Size(), outputVectorView2.Size()); + WINML_EXPECT_EQUAL(outputVectorView1.Size(), outputVectorView2.Size()); bool isSame = true; for (uint32_t i = 0; i < outputVectorView1.Size(); ++i) { @@ -614,5 +627,32 @@ TEST_F(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) break; } } - EXPECT_FALSE(isSame); + WINML_EXPECT_FALSE(isSame); } + +const LearningModelBindingAPITestApi& getapi() { + static constexpr LearningModelBindingAPITestApi api = + { + LearningModelBindingAPITestSetup, + LearningModelBindingAPITestGpuSetup, + CpuSqueezeNet, + CpuSqueezeNetEmptyOutputs, + CpuSqueezeNetUnboundOutputs, + CpuSqueezeNetBindInputTensorAsInspectable, + CastMapInt64, + DictionaryVectorizerMapInt64, + DictionaryVectorizerMapString, + ZipMapInt64, + ZipMapInt64Unbound, + ZipMapString, + GpuSqueezeNet, + GpuSqueezeNetEmptyOutputs, + GpuSqueezeNetUnboundOutputs, + ImageBindingDimensions, + VerifyInvalidBindExceptions, + BindInvalidInputName, + VerifyOutputAfterEvaluateAsyncCalledTwice, + VerifyOutputAfterImageBindCalledTwice + }; + return api; +} \ No newline at end of file diff --git a/winml/test/api/LearningModelBindingAPITest.h b/winml/test/api/LearningModelBindingAPITest.h new file mode 100644 index 0000000000000..c93be87c3cb60 --- /dev/null +++ b/winml/test/api/LearningModelBindingAPITest.h @@ -0,0 +1,49 @@ +#include "test.h" + +struct LearningModelBindingAPITestApi { + SetupTest LearningModelBindingAPITestSetup; + SetupTest LearningModelBindingAPITestGpuSetup; + VoidTest CpuSqueezeNet; + VoidTest CpuSqueezeNetEmptyOutputs; + VoidTest CpuSqueezeNetUnboundOutputs; + VoidTest CpuSqueezeNetBindInputTensorAsInspectable; + VoidTest CastMapInt64; + VoidTest DictionaryVectorizerMapInt64; + VoidTest DictionaryVectorizerMapString; + VoidTest ZipMapInt64; + VoidTest ZipMapInt64Unbound; + VoidTest ZipMapString; + VoidTest GpuSqueezeNet; + VoidTest GpuSqueezeNetEmptyOutputs; + VoidTest GpuSqueezeNetUnboundOutputs; + VoidTest ImageBindingDimensions; + VoidTest VerifyInvalidBindExceptions; + VoidTest BindInvalidInputName; + VoidTest VerifyOutputAfterEvaluateAsyncCalledTwice; + VoidTest VerifyOutputAfterImageBindCalledTwice; +}; +const LearningModelBindingAPITestApi& getapi(); + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelBindingAPITest, LearningModelBindingAPITestSetup) +WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNet) +WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetEmptyOutputs) +WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetUnboundOutputs) +WINML_TEST(LearningModelBindingAPITest, CpuSqueezeNetBindInputTensorAsInspectable) +WINML_TEST(LearningModelBindingAPITest, CastMapInt64) +WINML_TEST(LearningModelBindingAPITest, DictionaryVectorizerMapInt64) +WINML_TEST(LearningModelBindingAPITest, DictionaryVectorizerMapString) +WINML_TEST(LearningModelBindingAPITest, ZipMapInt64) +WINML_TEST(LearningModelBindingAPITest, ZipMapInt64Unbound) +WINML_TEST(LearningModelBindingAPITest, ZipMapString) +WINML_TEST(LearningModelBindingAPITest, VerifyOutputAfterEvaluateAsyncCalledTwice) +WINML_TEST(LearningModelBindingAPITest, VerifyOutputAfterImageBindCalledTwice) +WINML_TEST_CLASS_END() + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelBindingAPITestGpu, LearningModelBindingAPITestGpuSetup) +WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNet) +WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNetEmptyOutputs) +WINML_TEST(LearningModelBindingAPITestGpu, GpuSqueezeNetUnboundOutputs) +WINML_TEST(LearningModelBindingAPITestGpu, ImageBindingDimensions) +WINML_TEST(LearningModelBindingAPITestGpu, VerifyInvalidBindExceptions) +WINML_TEST(LearningModelBindingAPITestGpu, BindInvalidInputName) +WINML_TEST_CLASS_END() \ No newline at end of file diff --git a/winml/test/api/LearningModelSessionAPITest.cpp b/winml/test/api/LearningModelSessionAPITest.cpp index bc6494a3a71ac..6ee0b3d57f751 100644 --- a/winml/test/api/LearningModelSessionAPITest.cpp +++ b/winml/test/api/LearningModelSessionAPITest.cpp @@ -1,6 +1,6 @@ #include "testPch.h" #include "APITest.h" - +#include "LearningModelSessionAPITest.h" #include "winrt/Windows.Storage.h" #include "DeviceHelpers.h" @@ -16,144 +16,151 @@ using namespace winrt::Windows::Foundation::Collections; using winrt::Windows::Foundation::IPropertyValue; -class LearningModelSessionAPITests : public APITest -{}; +static void LearningModelSessionAPITestSetup() { + init_apartment(); +} -class LearningModelSessionAPITestsGpu : public APITest -{ -protected: - void SetUp() override - { - GPUTEST - } -}; +static void LearningModelSessionAPITestGpuSetup() { + GPUTEST; + init_apartment(); +} -class LearningModelSessionAPITestsSkipEdgeCore : public LearningModelSessionAPITestsGpu -{ -protected: - void SetUp() override - { - LearningModelSessionAPITestsGpu::SetUp(); - SKIP_EDGECORE - } -}; +static void LearningModelSessionAPITestsSkipEdgeCoreSetup() { + LearningModelSessionAPITestGpuSetup(); + SKIP_EDGECORE +} -TEST_F(LearningModelSessionAPITests, CreateSessionDeviceDefault) +static void CreateSessionDeviceDefault() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); } -TEST_F(LearningModelSessionAPITests, CreateSessionDeviceCpu) +static void CreateSessionDeviceCpu() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Cpu)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Cpu)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); // for the CPU device, make sure that we get back NULL and 0 for any device properties - EXPECT_FALSE(m_device.Direct3D11Device()); + WINML_EXPECT_EQUAL(learningModelDevice.Direct3D11Device(), nullptr); LARGE_INTEGER id; - id.QuadPart = GetAdapterIdQuadPart(); - EXPECT_EQ(id.LowPart, static_cast(0)); - EXPECT_EQ(id.HighPart, 0); + id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice); + WINML_EXPECT_EQUAL(id.LowPart, static_cast(0)); + WINML_EXPECT_EQUAL(id.HighPart, 0); } -TEST_F(LearningModelSessionAPITests, CreateSessionWithModelLoadedFromStream) +static void CreateSessionWithModelLoadedFromStream() { + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; std::wstring path = FileHelpers::GetModulePath() + L"model.onnx"; auto storageFile = winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path).get(); - EXPECT_NO_THROW(m_model = LearningModel::LoadFromStream(storageFile)); + WINML_EXPECT_NO_THROW(learningModel = LearningModel::LoadFromStream(storageFile)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::Default)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::Default)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); } -TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectX) +static void CreateSessionDeviceDirectX() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectX)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectX)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); } -TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectXHighPerformance) +static void CreateSessionDeviceDirectXHighPerformance() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); } -TEST_F(LearningModelSessionAPITestsGpu, CreateSessionDeviceDirectXMinimumPower) +static void CreateSessionDeviceDirectXMinimumPower() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); - EXPECT_NO_THROW(m_device = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower)); - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); + WINML_EXPECT_NO_THROW(learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower)); + WINML_EXPECT_NO_THROW(LearningModelSession(learningModel, learningModelDevice)); } -TEST_F(LearningModelSessionAPITestsSkipEdgeCore, AdapterIdAndDevice) -{ - EXPECT_NO_THROW(LoadModel(L"model.onnx")); +static void AdapterIdAndDevice() { + LearningModel learningModel = nullptr; + LearningModelDevice learningModelDevice = nullptr; + LearningModelSession learningModelSession = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); com_ptr factory; - EXPECT_HRESULT_SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory6), factory.put_void())); + WINML_EXPECT_HRESULT_SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory6), factory.put_void())); com_ptr adapter; - m_device = LearningModelDevice(LearningModelDeviceKind::DirectX); - EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapters(0, adapter.put())); + learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectX); + WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapters(0, adapter.put())); DXGI_ADAPTER_DESC desc; - EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); + WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); LARGE_INTEGER id; - id.QuadPart = GetAdapterIdQuadPart(); - EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart); - EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart); - EXPECT_TRUE(m_device.Direct3D11Device() != nullptr); + id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice); + WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart); + WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart); + WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr); - m_device = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance); + learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXHighPerformance); adapter = nullptr; - EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof(IDXGIAdapter), adapter.put_void())); - EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); - id.QuadPart = GetAdapterIdQuadPart(); - EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart); - EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart); - EXPECT_TRUE(m_device.Direct3D11Device() != nullptr); + WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof(IDXGIAdapter), adapter.put_void())); + WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); + id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice); + WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart); + WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart); + WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr); adapter = nullptr; - m_device = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower); - EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_MINIMUM_POWER, __uuidof(IDXGIAdapter), adapter.put_void())); - EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); - id.QuadPart = GetAdapterIdQuadPart(); - EXPECT_EQ(desc.AdapterLuid.LowPart, id.LowPart); - EXPECT_EQ(desc.AdapterLuid.HighPart, id.HighPart); - EXPECT_TRUE(m_device.Direct3D11Device() != nullptr); - - EXPECT_NO_THROW(m_session = LearningModelSession(m_model, m_device)); - EXPECT_EQ(m_session.Device().AdapterId(), m_device.AdapterId()); + learningModelDevice = LearningModelDevice(LearningModelDeviceKind::DirectXMinPower); + WINML_EXPECT_HRESULT_SUCCEEDED(factory->EnumAdapterByGpuPreference(0, DXGI_GPU_PREFERENCE_MINIMUM_POWER, __uuidof(IDXGIAdapter), adapter.put_void())); + WINML_EXPECT_HRESULT_SUCCEEDED(adapter->GetDesc(&desc)); + id.QuadPart = APITest::GetAdapterIdQuadPart(learningModelDevice); + WINML_EXPECT_EQUAL(desc.AdapterLuid.LowPart, id.LowPart); + WINML_EXPECT_EQUAL(desc.AdapterLuid.HighPart, id.HighPart); + WINML_EXPECT_TRUE(learningModelDevice.Direct3D11Device() != nullptr); + + WINML_EXPECT_NO_THROW(learningModelSession = LearningModelSession(learningModel, learningModelDevice)); + WINML_EXPECT_EQUAL(learningModelSession.Device().AdapterId(), learningModelDevice.AdapterId()); } -TEST_F(LearningModelSessionAPITests, EvaluateFeatures) +static void EvaluateFeatures() { std::vector shape = { 4 }; std::vector data = { L"one", L"two", L"three", L"four" }; // create from buffer auto tensor = TensorString::CreateFromArray(shape, data); - EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); // create from vector view auto dataCopy = data; tensor = TensorString::CreateFromIterable( shape, winrt::single_threaded_vector(std::move(dataCopy)).GetView()); - EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); - EXPECT_NO_THROW(LoadModel(L"id-tensor-string.onnx")); - LearningModelSession session(m_model); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"id-tensor-string.onnx", learningModel)); + LearningModelSession session(learningModel); auto outputTensor = TensorString::Create(); @@ -164,29 +171,30 @@ TEST_F(LearningModelSessionAPITests, EvaluateFeatures) session.EvaluateFeatures(featureswinrtmap, L"0"); // verify identity model round-trip works - EXPECT_EQ(outputTensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(outputTensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView()))); } -TEST_F(LearningModelSessionAPITests, EvaluateFeaturesAsync) +static void EvaluateFeaturesAsync() { std::vector shape = { 4 }; std::vector data = { L"one", L"two", L"three", L"four" }; // create from buffer auto tensor = TensorString::CreateFromArray(shape, data); - EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); // create from vector view auto dataCopy = data; tensor = TensorString::CreateFromIterable( shape, winrt::single_threaded_vector(std::move(dataCopy)).GetView()); - EXPECT_EQ(tensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(tensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(tensor.GetAsVectorView()))); - EXPECT_NO_THROW(LoadModel(L"id-tensor-string.onnx")); - LearningModelSession session(m_model); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"id-tensor-string.onnx", learningModel)); + LearningModelSession session(learningModel); auto outputTensor = TensorString::Create(shape); @@ -197,37 +205,39 @@ TEST_F(LearningModelSessionAPITests, EvaluateFeaturesAsync) session.EvaluateFeaturesAsync(featureswinrtmap, L"0").get(); // verify identity model round-trip works - EXPECT_EQ(outputTensor.GetAsVectorView().Size(), data.size()); - EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView()))); + WINML_EXPECT_EQUAL(outputTensor.GetAsVectorView().Size(), data.size()); + WINML_EXPECT_TRUE(std::equal(data.cbegin(), data.cend(), begin(outputTensor.GetAsVectorView()))); } -TEST_F(LearningModelSessionAPITests, EvaluationProperties) +static void EvaluationProperties() { // load a model - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); // create a session - m_session = LearningModelSession(m_model); + LearningModelSession learningModelSession = nullptr; + learningModelSession = LearningModelSession(learningModel); // set a property auto value = winrt::Windows::Foundation::PropertyValue::CreateBoolean(true); - m_session.EvaluationProperties().Insert(L"propName1", value); + learningModelSession.EvaluationProperties().Insert(L"propName1", value); // get the property and make sure it's there with the right value - auto value2 = m_session.EvaluationProperties().Lookup(L"propName1"); - EXPECT_EQ(value2.as().GetBoolean(), true); + auto value2 = learningModelSession.EvaluationProperties().Lookup(L"propName1"); + WINML_EXPECT_EQUAL(value2.as().GetBoolean(), true); } static LearningModelSession CreateSession(LearningModel model) { LearningModelDevice device(nullptr); - EXPECT_NO_THROW(device = LearningModelDevice(LearningModelDeviceKind::DirectX)); + WINML_EXPECT_NO_THROW(device = LearningModelDevice(LearningModelDeviceKind::DirectX)); LearningModelSession session(nullptr); if (DeviceHelpers::IsFloat16Supported(device)) { - EXPECT_NO_THROW(session = LearningModelSession(model, device)); + WINML_EXPECT_NO_THROW(session = LearningModelSession(model, device)); } else { - EXPECT_THROW_SPECIFIC( + WINML_EXPECT_THROW_SPECIFIC( session = LearningModelSession(model, device), winrt::hresult_error, [](const winrt::hresult_error& e) -> bool @@ -239,26 +249,28 @@ static LearningModelSession CreateSession(LearningModel model) return session; } -TEST_F(LearningModelSessionAPITestsGpu, CreateSessionWithCastToFloat16InModel) +static void CreateSessionWithCastToFloat16InModel() { // load a model - EXPECT_NO_THROW(LoadModel(L"fp16-truncate-with-cast.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"fp16-truncate-with-cast.onnx", learningModel)); - CreateSession(m_model); + CreateSession(learningModel); } -TEST_F(LearningModelSessionAPITestsGpu, DISABLED_CreateSessionWithFloat16InitializersInModel) +static void DISABLED_CreateSessionWithFloat16InitializersInModel() { // Disabled due to https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/21624720: // Model fails to resolve due to ORT using incorrect IR version within partition // load a model - EXPECT_NO_THROW(LoadModel(L"fp16-initializer.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"fp16-initializer.onnx", learningModel)); - CreateSession(m_model); + CreateSession(learningModel); } -static void EvaluateSessionAndCloseModel( +static void EvaluateSessionAndCloseModelHelper( LearningModelDeviceKind kind, bool close_model_on_session_creation) { @@ -275,7 +287,7 @@ static void EvaluateSessionAndCloseModel( // ensure you can create a session from the model LearningModelSession session(nullptr); - EXPECT_NO_THROW(session = LearningModelSession(model, device, options)); + WINML_EXPECT_NO_THROW(session = LearningModelSession(model, device, options)); std::vector input(1000); std::iota(std::begin(input), std::end(input), 0.0f); @@ -284,12 +296,12 @@ static void EvaluateSessionAndCloseModel( binding.Bind(L"input", tensor_input); LearningModelEvaluationResult result(nullptr); - EXPECT_NO_THROW(result = session.Evaluate(binding, L"")); + WINML_EXPECT_NO_THROW(result = session.Evaluate(binding, L"")); if (close_model_on_session_creation) { // ensure that the model has been closed - EXPECT_THROW_SPECIFIC( + WINML_EXPECT_THROW_SPECIFIC( LearningModelSession(model, device, options), winrt::hresult_error, [](const winrt::hresult_error& e) -> bool @@ -299,19 +311,20 @@ static void EvaluateSessionAndCloseModel( } else { - EXPECT_NO_THROW(LearningModelSession(model, device, options)); + WINML_EXPECT_NO_THROW(LearningModelSession(model, device, options)); } } -TEST_F(LearningModelSessionAPITests, EvaluateSessionAndCloseModel) +static void EvaluateSessionAndCloseModel() { - EXPECT_NO_THROW(::EvaluateSessionAndCloseModel(LearningModelDeviceKind::Cpu, true)); - EXPECT_NO_THROW(::EvaluateSessionAndCloseModel(LearningModelDeviceKind::Cpu, false)); + WINML_EXPECT_NO_THROW(::EvaluateSessionAndCloseModelHelper(LearningModelDeviceKind::Cpu, true)); + WINML_EXPECT_NO_THROW(::EvaluateSessionAndCloseModelHelper(LearningModelDeviceKind::Cpu, false)); } -TEST_F(LearningModelSessionAPITests, CloseSession) +static void CloseSession() { - EXPECT_NO_THROW(LoadModel(L"model.onnx")); + LearningModel learningModel = nullptr; + WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", learningModel)); LearningModelSession session = nullptr; /* @@ -329,7 +342,7 @@ TEST_F(LearningModelSessionAPITests, CloseSession) SIZE_T afterSessionCloseWorkingSetSize = 0; bool getProcessMemoryInfoSuccess = false; */ - EXPECT_NO_THROW(session = LearningModelSession(m_model)); + WINML_EXPECT_NO_THROW(session = LearningModelSession(learningModel)); /* // Get the current process memory info after session creation. @@ -341,7 +354,7 @@ TEST_F(LearningModelSessionAPITests, CloseSession) beforeSessionCloseWorkingSetSize = pmc.WorkingSetSize; pmc = { 0 }; */ - EXPECT_NO_THROW(session.Close()); + WINML_EXPECT_NO_THROW(session.Close()); /* Bug 23659026: Working set difference tolerance is too tight for LearningModelSessionAPITests::CloseSession @@ -367,17 +380,41 @@ TEST_F(LearningModelSessionAPITests, CloseSession) */ // verify that model still has metadata info after session close - std::wstring author(m_model.Author()); - EXPECT_EQ(author, L"onnx-caffe2"); + std::wstring author(learningModel.Author()); + WINML_EXPECT_EQUAL(author, L"onnx-caffe2"); // verify that session throws RO_E_CLOSED error std::vector input(1 * 3 * 224 * 224, 0); std::vector shape = { 1, 3, 224, 224 }; auto tensor_input = TensorFloat::CreateFromShapeArrayAndDataArray(shape, input); - EXPECT_THROW_SPECIFIC(LearningModelBinding binding(session), + WINML_EXPECT_THROW_SPECIFIC(LearningModelBinding binding(session), winrt::hresult_error, [](const winrt::hresult_error &e) -> bool { return e.code() == RO_E_CLOSED; }); } + +const LearningModelSesssionAPITestApi& getapi() { + static constexpr LearningModelSesssionAPITestApi api = + { + LearningModelSessionAPITestSetup, + LearningModelSessionAPITestGpuSetup, + LearningModelSessionAPITestsSkipEdgeCoreSetup, + CreateSessionDeviceDefault, + CreateSessionDeviceCpu, + CreateSessionWithModelLoadedFromStream, + CreateSessionDeviceDirectX, + CreateSessionDeviceDirectXHighPerformance, + CreateSessionDeviceDirectXMinimumPower, + AdapterIdAndDevice, + EvaluateFeatures, + EvaluateFeaturesAsync, + EvaluationProperties, + CreateSessionWithCastToFloat16InModel, + DISABLED_CreateSessionWithFloat16InitializersInModel, + EvaluateSessionAndCloseModel, + CloseSession, + }; + return api; +} \ No newline at end of file diff --git a/winml/test/api/LearningModelSessionAPITest.h b/winml/test/api/LearningModelSessionAPITest.h new file mode 100644 index 0000000000000..b98cb56f9fbd7 --- /dev/null +++ b/winml/test/api/LearningModelSessionAPITest.h @@ -0,0 +1,44 @@ +#include "test.h" + +struct LearningModelSesssionAPITestApi { + SetupTest LearningModelSessionAPITestSetup; + SetupTest LearningModelSessionAPITestGpuSetup; + SetupTest LearningModelSessionAPITestsSkipEdgeCoreSetup; + VoidTest CreateSessionDeviceDefault; + VoidTest CreateSessionDeviceCpu; + VoidTest CreateSessionWithModelLoadedFromStream; + VoidTest CreateSessionDeviceDirectX; + VoidTest CreateSessionDeviceDirectXHighPerformance; + VoidTest CreateSessionDeviceDirectXMinimumPower; + VoidTest AdapterIdAndDevice; + VoidTest EvaluateFeatures; + VoidTest EvaluateFeaturesAsync; + VoidTest EvaluationProperties; + VoidTest CreateSessionWithCastToFloat16InModel; + VoidTest DISABLED_CreateSessionWithFloat16InitializersInModel; + VoidTest EvaluateSessionAndCloseModel; + VoidTest CloseSession; +}; +const LearningModelSesssionAPITestApi& getapi(); + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITest, LearningModelSessionAPITestSetup) +WINML_TEST(LearningModelSessionAPITest, CreateSessionDeviceDefault) +WINML_TEST(LearningModelSessionAPITest,CreateSessionDeviceCpu) +WINML_TEST(LearningModelSessionAPITest,CreateSessionWithModelLoadedFromStream) +WINML_TEST(LearningModelSessionAPITest,EvaluateFeatures) +WINML_TEST(LearningModelSessionAPITest,EvaluateFeaturesAsync) +WINML_TEST(LearningModelSessionAPITest,EvaluationProperties) +WINML_TEST(LearningModelSessionAPITest,EvaluateSessionAndCloseModel) +WINML_TEST_CLASS_END() + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITestGpu, LearningModelSessionAPITestGpuSetup) +WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectX) +WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectXHighPerformance) +WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionDeviceDirectXMinimumPower) +WINML_TEST(LearningModelSessionAPITestGpu, CreateSessionWithCastToFloat16InModel) +WINML_TEST(LearningModelSessionAPITestGpu, DISABLED_CreateSessionWithFloat16InitializersInModel) +WINML_TEST_CLASS_END() + +WINML_TEST_CLASS_BEGIN_WITH_SETUP(LearningModelSessionAPITestsSkipEdgeCore, LearningModelSessionAPITestsSkipEdgeCoreSetup) +WINML_TEST(LearningModelSessionAPITestsSkipEdgeCore, AdapterIdAndDevice) +WINML_TEST_CLASS_END() \ No newline at end of file diff --git a/winml/test/common/googleTestMacros.h b/winml/test/common/googleTestMacros.h index 55fb2f7f740fe..dc38c6402f005 100644 --- a/winml/test/common/googleTestMacros.h +++ b/winml/test/common/googleTestMacros.h @@ -30,17 +30,34 @@ #define GTEST_SKIP GTEST_SKIP_("") #endif +#define EXPECT_THROW_SPECIFIC(statement, exception, condition) \ + EXPECT_THROW( \ + try { \ + statement; \ + } catch (const exception& e) { \ + EXPECT_TRUE(condition(e)); \ + throw; \ + } \ + , exception); + +#ifndef INSTANTIATE_TEST_SUITE_P +// Use the old name, removed in newer versions of googletest +#define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P +#endif + #define WINML_SKIP_TEST(message) \ GTEST_SKIP() << message; #define WINML_EXPECT_NO_THROW(statement) EXPECT_NO_THROW(statement) #define WINML_EXPECT_TRUE(statement) EXPECT_TRUE(statement) +#define WINML_EXPECT_FALSE(statement) EXPECT_FALSE(statement) #define WINML_EXPECT_EQUAL(val1, val2) EXPECT_EQ(val1, val2) #define WINML_EXPECT_NOT_EQUAL(val1, val2) EXPECT_NE(val1, val2) #define WINML_LOG_ERROR(message) \ ADD_FAILURE() << message - +#define WINML_LOG_COMMENT(message)\ + SCOPED_TRACE(message) #define WINML_EXPECT_HRESULT_SUCCEEDED(hresult_expression) EXPECT_HRESULT_SUCCEEDED(hresult_expression) #define WINML_EXPECT_HRESULT_FAILED(hresult_expression) EXPECT_HRESULT_FAILED(hresult_expression) #define WINML_EXPECT_THROW_SPECIFIC(statement, exception, condition) EXPECT_THROW_SPECIFIC(statement, exception, condition) diff --git a/winml/test/common/std.h b/winml/test/common/std.h index 162915abd02fd..d6eab75f645f8 100644 --- a/winml/test/common/std.h +++ b/winml/test/common/std.h @@ -29,19 +29,4 @@ #include "comp_generated/winrt/windows.ai.machinelearning.h" // WinML -#include "Windows.AI.MachineLearning.Native.h" - -#define EXPECT_THROW_SPECIFIC(statement, exception, condition) \ - EXPECT_THROW( \ - try { \ - statement; \ - } catch (const exception& e) { \ - EXPECT_TRUE(condition(e)); \ - throw; \ - } \ - , exception); - -#ifndef INSTANTIATE_TEST_SUITE_P -// Use the old name, removed in newer versions of googletest -#define INSTANTIATE_TEST_SUITE_P INSTANTIATE_TEST_CASE_P -#endif \ No newline at end of file +#include "Windows.AI.MachineLearning.Native.h" \ No newline at end of file diff --git a/winml/test/common/taefTestMacros.h b/winml/test/common/taefTestMacros.h index 7c7636b7a4dda..06d9048d7c6ff 100644 --- a/winml/test/common/taefTestMacros.h +++ b/winml/test/common/taefTestMacros.h @@ -30,11 +30,13 @@ using namespace WEX::TestExecution; #define WINML_EXPECT_NO_THROW(statement) VERIFY_NO_THROW(statement) #define WINML_EXPECT_TRUE(statement) VERIFY_IS_TRUE(statement) +#define WINML_EXPECT_FALSE(statement) VERIFY_IS_FALSE(statement) #define WINML_EXPECT_EQUAL(val1, val2) VERIFY_ARE_EQUAL(val1, val2) #define WINML_EXPECT_NOT_EQUAL(val1, val2) VERIFY_ARE_NOT_EQUAL(val1, val2) #define WINML_LOG_ERROR(message) \ VERIFY_FAIL(std::wstring_convert>().from_bytes(message).c_str()) - +#define WINML_LOG_COMMENT(message)\ + WEX::Logging::Log::Comment(std::wstring_convert>().from_bytes(message).c_str()) #define WINML_EXPECT_HRESULT_SUCCEEDED(hresult_expression) VERIFY_SUCCEEDED(hresult_expression) #define WINML_EXPECT_THROW_SPECIFIC(statement, exception, condition) VERIFY_THROWS_SPECIFIC(statement, exception, condition) #define WINML_EXPECT_HRESULT_FAILED(hresult_expression) VERIFY_FAILED(hresult_expression)