Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tools/clang/unittests/HLSLExec/LongVectorOps.def
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ OP_DEFAULT_DEFINES(UnaryMath, Frexp, 1, "TestFrexp", "", " -DFUNC_FREXP=1")
OP_DEFAULT(FloatSpecial, IsFinite, 1, "isfinite", "")
OP_DEFAULT(FloatSpecial, IsInf, 1, "isinf", "")
OP_DEFAULT(FloatSpecial, IsNan, 1, "isnan", "")
OP(FloatSpecial, ModF, 1, "TestModF", "", " -DFUNC_TEST_MODF=1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
OP(FloatSpecial, ModF, 1, "TestModF", "", " -DFUNC_TEST_MODF=1",
OP_DEFAULT_DEFINES(FloatSpecial, ModF, 1, "TestModF", "", " -DFUNC_TEST_MODF=1")

"LongVectorOp", Default1, Default2, Default3)

OP_DEFAULT(BinaryComparison, LessThan, 2, "", "<")
OP_DEFAULT(BinaryComparison, LessEqual, 2, "", "<=")
Expand Down
78 changes: 46 additions & 32 deletions tools/clang/unittests/HLSLExec/LongVectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ static constexpr Operation Operations[] = {
#include "LongVectorOps.def"
};

#define OP_WITH_OUT_PARAM(OPERATION, TYPE, IMPL) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define OP_WITH_OUT_PARAM(OPERATION, TYPE, IMPL) \
#define OP_WITH_OUT_PARAM_=(OPERATION, TYPE, IMPL) \

Given that we're restricting this to unary ops I think we can clarify that by appending the 1 in the name like some of the other macros do

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think it would be better to put this macro with the other similar class of macro definitions around line 625.
The #define OP_1" etc

template <> struct ExpectedBuilder<OpType::OPERATION, TYPE> { \
static std::vector<TYPE> buildExpected(Op<OpType::OPERATION, TYPE, 1>, \
const InputSets<TYPE> &Inputs) { \
DXASSERT_NOMSG(Inputs.size() == 1); \
size_t VectorSize = Inputs[0].size(); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
size_t VectorSize = Inputs[0].size(); \
const size_t VectorSize = Inputs[0].size(); \

std::vector<TYPE> Expected; \
Expected.resize(VectorSize * 2); \
for (size_t I = 0; I < VectorSize; ++I) { \
IMPL \
} \
return Expected; \
} \
};

constexpr const Operation &getOperation(OpType Op) {
if (Op < OpType::NumOpTypes)
return Operations[unsigned(Op)];
Expand Down Expand Up @@ -1015,41 +1030,21 @@ DEFAULT_OP_1(OpType::Log2, (std::log2(A)));
// with special logic. Frexp is only supported for fp32 values.
template <> struct Op<OpType::Frexp, float, 1> : DefaultValidation<float> {};

template <> struct ExpectedBuilder<OpType::Frexp, float> {
static std::vector<float> buildExpected(Op<OpType::Frexp, float, 1> &,
const InputSets<float> &Inputs) {
DXASSERT_NOMSG(Inputs.size() == 1);

// Expected values size is doubled. In the first half we store the
// Mantissas and in the second half we store the Exponents. This way we
// can leverage the existing logic which verify expected values in a
// single vector. We just need to make sure that we organize the output in
// the same way in the shader and when we read it back.
OP_WITH_OUT_PARAM(Frexp, float, {
int Exp = 0;
float Man = std::frexp(Inputs[0][I], &Exp);

size_t VectorSize = Inputs[0].size();

std::vector<float> Expected;
Expected.resize(VectorSize * 2);

for (size_t I = 0; I < VectorSize; ++I) {
int Exp = 0;
float Man = std::frexp(Inputs[0][I], &Exp);
// std::frexp returns a signed mantissa. But the HLSL implmentation
// returns an unsigned mantissa.
Man = std::abs(Man);

// std::frexp returns a signed mantissa. But the HLSL implmentation
// returns an unsigned mantissa.
Man = std::abs(Man);
Expected[I] = Man;

Expected[I] = Man;

// std::frexp returns the exponent as an int, but HLSL stores it as a
// float. However, the HLSL exponents fractional component is always 0.
// So it can conversion between float and int is safe.
Expected[I + VectorSize] = static_cast<float>(Exp);
}

return Expected;
}
};
// std::frexp returns the exponent as an int, but HLSL stores it as a
// float. However, the HLSL exponents fractional component is always 0.
// So it can conversion between float and int is safe.
Expected[I + VectorSize] = static_cast<float>(Exp);
});

//
// Binary Comparison
Expand Down Expand Up @@ -1236,6 +1231,23 @@ FLOAT_SPECIAL_OP(OpType::IsInf, (std::isinf(A)));
FLOAT_SPECIAL_OP(OpType::IsNan, (std::isnan(A)));
#undef FLOAT_SPECIAL_OP

template <typename T> struct Op<OpType::ModF, T, 1> : DefaultValidation<T> {};

OP_WITH_OUT_PARAM(ModF, float, {
float Exp = 0.0f;
float Man = std::modf(Inputs[0][I], &Exp);
Expected[I] = Man;
Expected[I + VectorSize] = Exp;
});

OP_WITH_OUT_PARAM(ModF, HLSLHalf_t, {
float Exp = 0.0f;
float Inp = float(Inputs[0][I]);
float Man = std::modf(Inp, &Exp);
Expected[I] = HLSLHalf_t(Man);
Expected[I + VectorSize] = HLSLHalf_t(Exp);
});

//
// dispatchTest
//
Expand Down Expand Up @@ -1772,10 +1784,12 @@ class DxilConf_SM69_Vectorized {
HLK_TEST(IsFinite, HLSLHalf_t);
HLK_TEST(IsInf, HLSLHalf_t);
HLK_TEST(IsNan, HLSLHalf_t);
HLK_TEST(ModF, HLSLHalf_t);

HLK_TEST(IsFinite, float);
HLK_TEST(IsInf, float);
HLK_TEST(IsNan, float);
HLK_TEST(ModF, float);

// Binary Comparison

Expand Down
14 changes: 14 additions & 0 deletions tools/clang/unittests/HLSLExec/ShaderOpArith.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4112,6 +4112,20 @@ void MSMain(uint GID : SV_GroupIndex,
}
#endif
#ifdef FUNC_TEST_MODF
vector<OUT_TYPE, NUM> TestModF(vector<TYPE, NUM> Vector)
{
vector<OUT_TYPE, NUM> Mantissa;
vector<OUT_TYPE, NUM> Exponent;
Mantissa = modf(Vector, Exponent);
g_OutputVector.Store< vector<OUT_TYPE, NUM> >(sizeof(OUT_TYPE) * NUM, Exponent);
return Mantissa;
}
#endif
#ifdef FUNC_SHUFFLE_VECTOR
vector<OUT_TYPE, NUM> TestShuffleVector(TYPE Scalar)
{
Expand Down