DirectMLX

DirectMLX, DirectML için C++ 'header-only' bir yardımcı kütüphanedir ve bireysel operatörleri grafikler halinde birleştirmeyi kolaylaştırır.

DirectMLX, tüm DirectML (DML) işleç türleri için kullanışlı sarmalayıcıların yanı sıra sezgisel operatör aşırı yüklemeleri de sağlar ve bu da DML işleçlerinin örneğini oluşturmanızı ve bunları karmaşık grafiklere zincirlemenizi kolaylaştırır.

Nerede bulunur? DirectMLX.h

DirectMLX.h , MIT lisansı altında açık kaynak yazılım olarak dağıtılır. En son sürümü DirectML GitHub'da bulabilirsiniz.

Sürüm gereksinimleri

DirectMLX, DirectML sürüm 1.4.0 veya üzerini gerektirir (bkz . DirectML sürüm geçmişi). DirectML'nin eski sürümleri desteklenmez.

DirectMLX.h, C++11 özellikli bir derleyici gerektirir( ancak bunlarla sınırlı değildir):

  • Visual Studio 2017
  • Visual Studio 2019
  • Çıncak 10

C++17 (veya daha yeni) derleyicisinin önerdiğimiz seçenek olduğunu unutmayın. C++11 için derleme mümkündür, ancak eksik standart kitaplık işlevselliğini değiştirmek için üçüncü taraf kitaplıklarının ( GSL ve Abseil gibi) kullanılmasını gerektirir.

derlemesi DirectMLX.hbaşarısız olan bir yapılandırmanız varsa lütfen GitHub'ımızda bir sorun oluşturun.

Temel kullanım

#include <DirectML.h>
#include <DirectMLX.h>

IDMLDevice* device;

/* ... */

dml::Graph graph(device);

// Input tensor of type FLOAT32 and sizes { 1, 2, 3, 4 }
auto x = dml::InputTensor(graph, 0, dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, {1, 2, 3, 4}));

// Create an operator to compute the square root of x
auto y = dml::Sqrt(x);

// Compile a DirectML operator from the graph. When executed, this compiled operator will compute
// the square root of its input.
DML_EXECUTION_FLAGS flags = DML_EXECUTION_FLAG_NONE;
ComPtr<IDMLCompiledOperator> op = graph.Compile(flags, { y });

// Now initialize and dispatch the DML operator as usual

İşte, ikinci dereceden formülü hesaplayabilen bir DirectML grafiği oluşturan başka bir örnek.

#include <DirectML.h>
#include <DirectMLX.h>

IDMLDevice* device;

/* ... */

std::pair<dml::Expression, dml::Expression>
    QuadraticFormula(dml::Expression a, dml::Expression b, dml::Expression c)
{
    // Quadratic formula: given an equation of the form ax^2 + bx + c = 0, x can be found by:
    //   x = -b +/- sqrt(b^2 - 4ac) / (2a)
    // https://en.wikipedia.org/wiki/Quadratic_formula

    // Note: DirectMLX provides operator overloads for common mathematical expressions. So for 
    // example a*c is equivalent to dml::Multiply(a, c).
    auto x1 = -b + dml::Sqrt(b*b - 4*a*c) / (2*a);
    auto x2 = -b - dml::Sqrt(b*b - 4*a*c) / (2*a);

    return { x1, x2 };
}

/* ... */

dml::Graph graph(device);

dml::TensorDimensions inputSizes = {1, 2, 3, 4};
auto a = dml::InputTensor(graph, 0, dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, inputSizes));
auto b = dml::InputTensor(graph, 1, dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, inputSizes));
auto c = dml::InputTensor(graph, 2, dml::TensorDesc(DML_TENSOR_DATA_TYPE_FLOAT32, inputSizes));

auto [x1, x2] = QuadraticFormula(a, b, c);

// When executed with input tensors a, b, and c, this compiled operator computes the two outputs
// of the quadratic formula, and returns them as two output tensors x1 and x2
DML_EXECUTION_FLAGS flags = DML_EXECUTION_FLAG_NONE;
ComPtr<IDMLCompiledOperator> op = graph.Compile(flags, { x1, x2 });

// Now initialize and dispatch the DML operator as usual

Diğer örnekler

DirectMLX kullanan eksiksiz örnekler DirectML GitHub deposunda bulunabilir.

Derleme zamanı seçenekleri

DirectMLX, derleme zamanında üst bilginin çeşitli bölümlerini özelleştirmek için #define'leri destekler.

Seçenek Açıklama
DMLX_NO_EXCEPTIONS Tanımlandığında, hataların bir özel durum fırlatmak yerine std::abort çağrısına yol açmasına neden olur. Özel durumlar kullanılamıyorsa (örneğin, derleyici seçeneklerinde özel durumlar devre dışı bırakılmışsa) bu varsayılan olarak tanımlanır.
DMLX_USE_WIL #define edildiğinde, Windows Uygulama Kitaplığı özel durum türleri kullanılarak özel durumlar fırlatılır. Aksi takdirde, bunun yerine standart özel durum türleri (örneğin std::runtime_error) kullanılır. DMLX_NO_EXCEPTIONS tanımlanırsa bu seçeneğin hiçbir etkisi olmaz.
DMLX_USE_ABSEIL #define ise, C++11'de kullanılamayan standart kitaplık türleri için açılır liste yerine Abseil kullanır. Bu türler arasında absl::optional (yerine std::optional), absl::Span (yerine std::span) ve absl::InlinedVectorbulunur.
DMLX_USE_GSL yerine GSL'ninstd::spankullanılıp kullanılmayacağını denetler. #define tanımlandıysa, std::span kullanımları, yerel gsl::span uygulamaları bulunmayan derleyicilerde std::span ile değiştirilir. Aksi takdirde, bunun yerine satır içi geçmeli bir uygulama sağlanır. Bu seçeneğin yalnızca C++20 öncesi bir derleyici üzerinde derleme yaparken std::span desteği olmadığında ve Abseil gibi başka bir yerine geçen standart kütüphane kullanılmadığında kullanıldığını unutmayın.

Tensor düzenini denetleme

Çoğu işleç için DirectMLX, operatörün çıkış tensorlarının özelliklerini sizin yerinize hesaplar. Örneğin, eksenler dml::Reduce arasında, boyutları { 0, 2, 3 } olan bir giriş tensörüyle { 3, 4, 5, 6 } işlemi gerçekleştirirken, DirectMLX çıkış tensörünün özelliklerini, doğru şekli { 1, 4, 1, 1 } dahil olmak üzere, otomatik olarak hesaplar.

Ancak, çıkış tensorunun diğer özellikleri Strides, TotalTensorSizeInBytes ve GuaranteedBaseOffsetAlignment'dır. Varsayılan olarak, DirectMLX bu özellikleri, tensörün adımlamaya sahip olmaması, garantili bir temel ofset hizalamasının bulunmaması ve toplam tensör boyutunun DMLCalcBufferTensorSize tarafından bayt cinsinden hesaplanması şeklinde ayarlar.

DirectMLX, tensor ilkeleri olarak bilinen nesneleri kullanarak bu çıkış tensor özelliklerini özelleştirme özelliğini destekler. TensorPolicy, DirectMLX tarafından tetiklenen özelleştirilebilir bir geri çağırmadır ve bir tensörün hesaplanan veri türü, bayrak değerleri ve boyutlarına göre çıktının tensör özelliklerini döndürür.

Tensor ilkeleri dml::Graph nesnesinde ayarlanabilir ve bu grafikteki sonraki tüm işleçler için kullanılır. Tensor ilkeleri, TensorDesc oluştururken doğrudan da ayarlanabilir.

Bu nedenle DirectMLX tarafından üretilen tensorların düzeni, tensorlarında uygun adımları ayarlayan bir TensorPolicy ayarlanarak denetlenebilir.

Örnek 1

// Define a policy, which is a function that returns a TensorProperties given a data type,
// flags, and sizes.
dml::TensorProperties MyCustomPolicy(
    DML_TENSOR_DATA_TYPE dataType,
    DML_TENSOR_FLAGS flags,
    Span<const uint32_t> sizes)
{
    // Compute your custom strides, total tensor size in bytes, and guaranteed base
    // offset alignment
    dml::TensorProperties props;
    props.strides = /* ... */;
    props.totalTensorSizeInBytes = /* ... */;
    props.guaranteedBaseOffsetAlignment = /* ... */;
    return props;
};

// Set the policy on the dml::Graph
dml::Graph graph(/* ... */);
graph.SetTensorPolicy(dml::TensorPolicy(&MyCustomPolicy));

Örnek 2

DirectMLX ayrıca bazı alternatif tensor ilkeleri de yerleşik olarak sağlar. Örneğin InterleavedChannel ilkesi, bir kolaylık olarak sağlanır ve tensorların NHWC sırasına göre yazılması için adımlarla oluşturulması amacıyla kullanılabilir.

// Set the InterleavedChannel policy on the dml::Graph
dml::Graph graph(/* ... */);
graph.SetTensorPolicy(dml::TensorPolicy::InterleavedChannel());

// When executed, the tensor `result` will be in NHWC layout (rather than the default NCHW)
auto result = dml::Convolution(/* ... */);

Ayrıca bakınız