Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
DirectMLX is een C++-helperbibliotheek die alleen headers gebruikt voor DirectML, bedoeld om het gemakkelijker te maken om individuele operators samen te stellen tot grafen.
DirectMLX biedt handige wrappers voor alle DML-operatortypen (DirectML), evenals intuïtieve operatoroverbelastingen, waardoor het eenvoudiger is om DML-operators te instantiëren en te koppelen aan complexe grafieken.
Waar vind ik? DirectMLX.h
DirectMLX.h wordt gedistribueerd als opensource-software onder de MIT-licentie. De nieuwste versie vindt u op De DirectML GitHub.
Versievereisten
DirectMLX vereist DirectML-versie 1.4.0 of hoger (zie de versiegeschiedenis van DirectML). Oudere versies van DirectML worden niet ondersteund.
DirectMLX.h vereist een C++11-compatibele compiler, waaronder (maar niet beperkt tot):
- Visual Studio 2017
- Visual Studio 2019
- Klang 10
Houd er rekening mee dat een C++17 -compiler (of nieuwer) de optie is die we aanbevelen. Compileren voor C++11 is mogelijk, maar hiervoor is het gebruik van bibliotheken van derden (zoals GSL en Abseil) vereist om ontbrekende standaardbibliotheekfunctionaliteit te vervangen.
Als u een configuratie hebt die niet kan worden gecompileerd DirectMLX.h, kunt u een probleem indienen op onze GitHub.
Basaal gebruik
#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
Hier volgt een ander voorbeeld, waarmee een DirectML-grafiek wordt gemaakt die de kwadratische formule kan berekenen.
#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
Meer voorbeelden
Volledige voorbeelden met DirectMLX vindt u in de DirectML GitHub-opslagplaats.
Compilatietijdopties
DirectMLX ondersteunt compileertijd #define's om verschillende onderdelen van de header aan te passen.
| Optie | Beschrijving |
|---|---|
| DMLX_NO_EXCEPTIONS | Als #define is ingesteld, leidt dit ertoe dat fouten resulteren in een oproep naar std::abort in plaats van dat er een uitzondering wordt gegenereerd. Dit wordt standaard gedefinieerd als uitzonderingen niet beschikbaar zijn (bijvoorbeeld als uitzonderingen zijn uitgeschakeld in de compileropties). |
| DMLX_USE_WIL | Als er worden gedefinieerd met #define, worden uitzonderingen opgeworpen met exception types van Windows Implementation Library. Anders worden standaard uitzonderingstypen (zoals std::runtime_error) gebruikt. Deze optie heeft geen effect als DMLX_NO_EXCEPTIONS is gedefinieerd. |
| DMLX_USE_ABSEIL | Als #define is gedefinieerd, gebruikt Abseil als directe vervangingen voor standaardbibliotheektypen die niet beschikbaar zijn in C++11. Deze typen omvatten absl::optional (in plaats van std::optional), absl::Span (in plaats van std::span), en absl::InlinedVector. |
| DMLX_USE_GSL | Hiermee bepaalt u of GSL moet worden gebruikt als vervanging voor std::span. Als #define is toegepast, worden gebruik van std::span vervangen door gsl::span door compilers zonder systeemeigen std::span implementaties. Anders wordt een inline drop-in-implementatie aangeboden. Houd er rekening mee dat deze optie alleen wordt gebruikt bij het compileren van een pre-C++20-compiler zonder ondersteuning voor std::spanen wanneer er geen andere standaardbibliotheekvervanging (zoals Abseil) wordt gebruikt. |
Tensor-indeling beheren
Voor de meeste operators berekent DirectMLX namens u de eigenschappen van de uitvoertenors van de operator. Wanneer u bijvoorbeeld een dml::Reduce over assen { 0, 2, 3 } uitvoert met een invoertenoren van afmetingen { 3, 4, 5, 6 }, berekent DirectMLX automatisch de eigenschappen van de uitvoertenoren, inclusief de juiste vorm van { 1, 4, 1, 1 }.
De andere eigenschappen van een uitvoertensor omvatten echter strides, TotalTensorSizeInBytes en GuaranteedBaseOffsetAlignment. Standaard stelt DirectMLX deze eigenschappen in, zodat de tensor geen striding heeft, geen gegarandeerde basisverschiluitlijning en een totale tensorgrootte in bytes zoals berekend door DMLCalcBufferTensorSize.
DirectMLX ondersteunt de mogelijkheid om deze uitvoertensoreigenschappen aan te passen, met behulp van objecten die tensor-beleid worden genoemd. Een TensorPolicy is een aanpasbare callback die wordt aangeroepen door DirectMLX en retourneert uitvoer-tensoreigenschappen op basis van het berekende gegevenstype, vlaggen en grootten van een tensor.
Tensor-beleid kan worden ingesteld op het dml::Graph-object en wordt gebruikt voor alle volgende operators in die grafiek. Tensor-beleid kan ook rechtstreeks worden ingesteld bij het maken van een TensorDesc.
De indeling van tensors die door DirectMLX worden geproduceerd, kan daarom worden bepaald door een TensorPolicy in te stellen die de juiste "strides" op zijn tensors instelt.
Voorbeeld 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));
Voorbeeld 2
DirectMLX biedt ook een aantal ingebouwde alternatieve tensor-beleidsregels. Het InterleavedChannel-beleid wordt bijvoorbeeld geleverd als een gemak en kan worden gebruikt om tensors met stappen te produceren, zodat ze in NHWC-volgorde worden geschreven.
// 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(/* ... */);