@@ -32,6 +32,7 @@
|
||||
#include "../common/cutlass_unit_test.h"
|
||||
|
||||
#include "cutlass/complex.h"
|
||||
#include "cutlass/constants.h"
|
||||
#include "cutlass/numeric_conversion.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -85,6 +86,42 @@ TEST(complex, f16_to_f32_conversion) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(complex, exp_f32) {
|
||||
|
||||
cutlass::complex<float> Z[] = {
|
||||
{1, 1},
|
||||
{2 , cutlass::constants::pi<float>()/2.0f },
|
||||
{0.5f, cutlass::constants::pi<float>() },
|
||||
{0.25f, cutlass::constants::pi<float>()*3/4.0f },
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
cutlass::complex<double> Expected[] = {
|
||||
{1.4686939399158851, 2.2873552871788423},
|
||||
{4.524491950137825e-16, 7.38905609893065},
|
||||
{-1.6487212707001282, 2.019101226849069e-16},
|
||||
{-0.9079430793557842, 0.9079430793557843},
|
||||
{1, 0}
|
||||
};
|
||||
|
||||
double tolerance = 0.00001;
|
||||
|
||||
for (int i = 0; cutlass::real(Z[i]); ++i) {
|
||||
double e_r = cutlass::real(Expected[i]);
|
||||
double e_i = cutlass::real(Expected[i]);
|
||||
|
||||
cutlass::complex<float> got = cutlass::exp(Z[i]);
|
||||
float g_r = cutlass::real(got);
|
||||
float g_i = cutlass::real(got);
|
||||
|
||||
EXPECT_TRUE(
|
||||
std::abs(g_r - e_r) < tolerance && std::abs(g_i - e_i) < tolerance
|
||||
) << "Expected(" << Expected[i] << "), Got(" << got << ")";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace test {
|
||||
|
||||
/// Thorough testing for basic complex math operators. Uses std::complex as a reference.
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "../common/cutlass_unit_test.h"
|
||||
|
||||
#include "cutlass/functional.h"
|
||||
#include "cutlass/core_io.h"
|
||||
|
||||
#include "cutlass/layout/matrix.h"
|
||||
#include "cutlass/util/host_tensor.h"
|
||||
@@ -78,16 +79,16 @@ __global__ void trinary_operator(
|
||||
|
||||
Operator op;
|
||||
|
||||
Element a_x = *a;
|
||||
Element b_x = *b;
|
||||
Element c_x = *c;
|
||||
Element a_x = a[blockIdx.x];
|
||||
Element b_x = b[blockIdx.x];
|
||||
Element c_x = c[blockIdx.x];
|
||||
|
||||
CUTLASS_PRAGMA_NO_UNROLL
|
||||
for (int i = 0; i < Iterations; ++i) {
|
||||
c_x = op(a_x, b_x, c_x);
|
||||
}
|
||||
|
||||
*d = c_x;
|
||||
d[blockIdx.x] = c_x;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -421,3 +422,67 @@ TEST(Functional, multiply_add_bf16x17) {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
cutlass::Quaternion<T> random_quaternion(int range) {
|
||||
return cutlass::Quaternion<T>{
|
||||
T((rand() % range * 2) - range),
|
||||
T((rand() % range * 2) - range),
|
||||
T((rand() % range * 2) - range),
|
||||
T((rand() % range * 2) - range)
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Functional_multiply_add_QuaternionT() {
|
||||
|
||||
using Element = cutlass::Quaternion<T>;
|
||||
using Operator = cutlass::multiply_add<Element, Element, Element>;
|
||||
using HostTensor = cutlass::HostTensor<Element, cutlass::layout::RowMajor>;
|
||||
|
||||
int const kM = 128;
|
||||
int const kRange = 8;
|
||||
|
||||
HostTensor A({kM, 1});
|
||||
HostTensor B({kM, 1});
|
||||
HostTensor C({kM, 1});
|
||||
HostTensor D({kM, 1});
|
||||
|
||||
srand(2021);
|
||||
|
||||
for (int m = 0; m < kM; ++m) {
|
||||
A.at({m, 0}) = random_quaternion<T>(kRange);
|
||||
B.at({m, 0}) = random_quaternion<T>(kRange);
|
||||
C.at({m, 0}) = random_quaternion<T>(kRange);
|
||||
}
|
||||
|
||||
A.sync_device();
|
||||
B.sync_device();
|
||||
C.sync_device();
|
||||
D.sync_device();
|
||||
|
||||
test::core::kernel::trinary_operator<Element, Operator><<< dim3(kM,1), dim3(1,1) >>>(
|
||||
D.device_data(),
|
||||
A.device_data(),
|
||||
B.device_data(),
|
||||
C.device_data()
|
||||
);
|
||||
|
||||
D.sync_host();
|
||||
|
||||
for (int m = 0; m < kM; ++m) {
|
||||
|
||||
Element a = A.at({m, 0});
|
||||
Element b = B.at({m, 0});
|
||||
Element c = C.at({m, 0});
|
||||
Element got = D.at({m, 0});
|
||||
Element expected = a * b + c;
|
||||
|
||||
EXPECT_TRUE(got == expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Functional, multiply_add_quaternion_f32) {
|
||||
Functional_multiply_add_QuaternionT<float>();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "../common/cutlass_unit_test.h"
|
||||
|
||||
#include "cutlass/matrix.h"
|
||||
#include "cutlass/core_io.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user