Skip to content

Commit

Permalink
Adding very basic Vector<int8_t, 64> support
Browse files Browse the repository at this point in the history
Included a quick test for included functionality.
Still need to find a proper solution for _mm_empty.
  • Loading branch information
JoshuaWierenga committed Aug 22, 2021
1 parent 7def1bb commit 1f4c242
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 114 deletions.
22 changes: 18 additions & 4 deletions Test/Test.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
#include <iostream>
#include <array>
#include "Vector.h"

void simple128test()
void test8_64()
{
const std::array<signed char, 8> array{ 1, 2, 3, 4, 5, 6, 7, 8 };
constexpr int value = -9, test = -3;

Vector<signed char, 64> v_array(array);
v_array += value;

//TODO Add an array cast so that items can be printed individually and then lined up
std::cout << "signed int8_t 64 bit test" << std::endl << v_array << std::endl << (v_array > test);
}

/*void simple128test()
{
constexpr int array[4] = { 4, 7, -2, 9 };
constexpr int value = 5, adjustment1 = 10, adjustment2 = 3;
Expand All @@ -23,10 +36,11 @@ void simple256test()
vArray += Blend(vArray > value, adjustment, 0);
std::cout << "simple 256 bit test" << std::endl << vArray << std::endl << std::endl;
}
}*/

int main()
{
simple128test();
simple256test();
test8_64();
//simple128test();
//simple256test();
}
85 changes: 29 additions & 56 deletions Vectors/Vector.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
//TODO Merge string info arrays into a single structure
//TODO Automate generation of typeVectorConstructorArguments
//TODO add _mm_empty for mmx operation call
#include <sstream>
#include <string>
#include "Vector.h"

struct VectorHelpers
{
//Vector ToString Functions
//TODO Check if these can be merged, doubt it though given use of vector_{128, 256}_, only works if GetInternal{128, 256} can be merged as well
//TODO Check if these can be merged, doubt it though given use of vector_{64, 128, 256}_, only works if GetInternal{64, 128, 256} can be merged as well
template <typename T>
static std::string ToString64i(const Vector<T, 64> vector)
{
std::stringstream sstr;
T values[8 / sizeof(T)];
std::memcpy(values, &vector.vector_64_, sizeof(values));

for (T v : values)
{
sstr << static_cast<int>(v) << " ";
}

return sstr.str();
}

template <typename T>
static std::string ToString128i(const Vector<T, 128> vector)
{
Expand Down Expand Up @@ -64,83 +80,40 @@ struct VectorHelpers
}
};

#pragma region Vector<int32_t, 128>
#pragma region Vector<int8_t, 64>
// Constructors
template <>
Vector<int32_t, 128>::Vector(const int32_t value) : vector_128_(_mm_set1_epi32(value))
Vector<int8_t, 64>::Vector(const int8_t value) : vector_64_(_mm_set1_pi8(value))
{
}

template <>
Vector<int32_t, 128>::Vector(const std::array<int32_t, 4> values) : vector_128_(_mm_setr_epi32(values[0], values[1], values[2], values[3]))
{
}

//TODO Fix for floating point types
std::ostream& operator<<(std::ostream& stream, const Vector<int32_t, 128>& vector)
{
return stream << VectorHelpers::ToString128i(vector);
}

//TODO Fix for floating point types
Vector<int32_t, 128> Blend(const Vector<int32_t, 128> comparision, const Vector<int32_t, 128> falseValue, const Vector<int32_t, 128> trueValue)
{
return VectorHelpers::GetVector128i<int32_t>(_mm_blendv_epi8(VectorHelpers::GetInternal128i(falseValue), VectorHelpers::GetInternal128i(trueValue), VectorHelpers::GetInternal128i(comparision)));
}

// Assignment Operators
template <>
Vector<int32_t, 128>& Vector<int32_t, 128>::operator+=(const Vector<int32_t, 128>& rhs)
{
this->vector_128_ = _mm_add_epi32(this->vector_128_, rhs.vector_128_);
return *this;
}

// Comparision Operators
template <>
Vector<int32_t, 128> Vector<int32_t, 128>::operator>(const Vector<int32_t, 128>& vector2) const
{
return _mm_cmpgt_epi32(this->vector_128_, vector2.vector_128_);
}
#pragma endregion

#pragma region Vector<int32_t, 256>
// Constructors
template <>
Vector<int32_t, 256>::Vector(const int32_t value) : vector_256_(_mm256_set1_epi32(value))
{
}

template <>
Vector<int32_t, 256>::Vector(const std::array<int32_t, 8> values) : vector_256_(_mm256_setr_epi32(values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]))
{
}

//TODO Fix for floating point types
std::ostream& operator<<(std::ostream& stream, const Vector<int32_t, 256>& vector)
Vector<int8_t, 64>::Vector(const std::array<int8_t, 8> values) : vector_64_(_mm_setr_pi8(values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]))
{
return stream << VectorHelpers::ToString256i(vector);
}

//TODO Fix for floating point types
Vector<int32_t, 256> Blend(const Vector<int32_t, 256> comparision, const Vector<int32_t, 256> falseValue, const Vector<int32_t, 256> trueValue)
std::ostream& operator<<(std::ostream& stream, const Vector<int8_t, 64>& vector)
{
return VectorHelpers::GetVector256i<int32_t>(_mm256_blendv_epi8(VectorHelpers::GetInternal256i(falseValue), VectorHelpers::GetInternal256i(trueValue), VectorHelpers::GetInternal256i(comparision)));
return stream << VectorHelpers::ToString64i(vector);
}

// Assignment Operators
template <>
Vector<int32_t, 256>& Vector<int32_t, 256>::operator+=(const Vector<int32_t, 256>& rhs)
Vector<int8_t, 64>& Vector<int8_t, 64>::operator+=(const Vector<int8_t, 64>& rhs)
{
this->vector_256_ = _mm256_add_epi32(this->vector_256_, rhs.vector_256_);
this->vector_64_ = _mm_add_pi8(this->vector_64_, rhs.vector_64_);
_mm_empty();
return *this;
}

// Comparision Operators
template <>
Vector<int32_t, 256> Vector<int32_t, 256>::operator>(const Vector<int32_t, 256>& vector2) const
Vector<int8_t, 64> Vector<int8_t, 64>::operator>(const Vector<int8_t, 64>& vector2) const
{
return _mm256_cmpgt_epi32(this->vector_256_, vector2.vector_256_);
const auto result = _mm_cmpgt_pi8(this->vector_64_, vector2.vector_64_);
_mm_empty();
return result;
}
#pragma endregion

42 changes: 26 additions & 16 deletions Vectors/Vector.cpp.tt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,37 @@
<#@ output extension="" #>
//TODO Merge string info arrays into a single structure
//TODO Automate generation of typeVectorConstructorArguments
<# var typeSizes = new int[] {32};
var vectorSizes = new int[] {128, 256};
//TODO add _mm_empty for mmx operation call
<# var typeSizes = new int[] {8};
var vectorSizes = new int[] {64};

var typeVectorSetArguments = new string[,] {{"values[0], values[1], values[2], values[3]"}, {"values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]"}};
var typeVectorSetArguments = new string[,] {{"values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7]"}};

var vectorSimdPrefixes = new string[] {"mm", "mm256"};
var typeSimdSuffixes = new string[] {"32"}; #>
var vectorSimdPrefixes = new string[] {"mm"};
var typeSimdSuffixes = new string[] {"pi8"}; #>
#include <sstream>
#include <string>
#include "Vector.h"

struct VectorHelpers
{
//Vector ToString Functions
//TODO Check if these can be merged, doubt it though given use of vector_{128, 256}_, only works if GetInternal{128, 256} can be merged as well
//TODO Check if these can be merged, doubt it though given use of vector_{64, 128, 256}_, only works if GetInternal{64, 128, 256} can be merged as well
template <typename T>
static std::string ToString64i(const Vector<T, 64> vector)
{
std::stringstream sstr;
T values[8 / sizeof(T)];
std::memcpy(values, &vector.vector_64_, sizeof(values));

for (T v : values)
{
sstr << static_cast<int>(v) << " ";
}

return sstr.str();
}

template <typename T>
static std::string ToString128i(const Vector<T, 128> vector)
{
Expand Down Expand Up @@ -93,12 +109,12 @@ struct VectorHelpers
#pragma region <#= typeVectorName #>
// Constructors
template <>
<#= typeVectorName #>::Vector(const <#= typeName #> value) : <#= vectorVariableName #>(_<#= vectorSimdPrefix #>_set1_epi<#= typeSimdSuffix #>(value))
<#= typeVectorName #>::Vector(const <#= typeName #> value) : <#= vectorVariableName #>(_<#= vectorSimdPrefix #>_set1_<#= typeSimdSuffix #>(value))
{
}

template <>
<#= typeVectorName #>::Vector(const std::array<<#= typeName #>, <#= vectorSize / typeSize #>> values) : <#= vectorVariableName #>(_<#= vectorSimdPrefix #>_setr_epi<#= typeSimdSuffix #>(<#= typeVectorSetArgument #>))
<#= typeVectorName #>::Vector(const std::array<<#= typeName #>, <#= vectorSize / typeSize #>> values) : <#= vectorVariableName #>(_<#= vectorSimdPrefix #>_setr_<#= typeSimdSuffix #>(<#= typeVectorSetArgument #>))
{
}

Expand All @@ -108,25 +124,19 @@ std::ostream& operator<<(std::ostream& stream, const <#= typeVectorName #>& vect
return stream << VectorHelpers::ToString<#= vectorSize #>i(vector);
}

//TODO Fix for floating point types
<#= typeVectorName #> Blend(const <#= typeVectorName #> comparision, const <#= typeVectorName #> falseValue, const <#= typeVectorName #> trueValue)
{
return VectorHelpers::GetVector<#= vectorSize #>i<<#= typeName #>>(_<#= vectorSimdPrefix #>_blendv_epi8(VectorHelpers::GetInternal<#= vectorSize #>i(falseValue), VectorHelpers::GetInternal<#= vectorSize #>i(trueValue), VectorHelpers::GetInternal<#= vectorSize #>i(comparision)));
}

// Assignment Operators
template <>
<#= typeVectorName #>& <#= typeVectorName #>::operator+=(const <#= typeVectorName #>& rhs)
{
this-><#= vectorVariableName #> = _<#= vectorSimdPrefix #>_add_epi<#= typeSize #>(this-><#= vectorVariableName #>, rhs.<#= vectorVariableName #>);
this-><#= vectorVariableName #> = _<#= vectorSimdPrefix #>_add_<#= typeSimdSuffix #>(this-><#= vectorVariableName #>, rhs.<#= vectorVariableName #>);
return *this;
}

// Comparision Operators
template <>
<#= typeVectorName #> <#= typeVectorName #>::operator>(const <#= typeVectorName #>& vector2) const
{
return _<#= vectorSimdPrefix #>_cmpgt_epi<#= typeSize #>(this-><#= vectorVariableName #>, vector2.<#= vectorVariableName #>);
return _<#= vectorSimdPrefix #>_cmpgt_<#= typeSimdSuffix #>(this-><#= vectorVariableName #>, vector2.<#= vectorVariableName #>);
}
#pragma endregion

Expand Down
45 changes: 16 additions & 29 deletions Vectors/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ class Vector
{
friend struct VectorHelpers;

__m128i vector_128_{};
__m256i vector_256_{};
__m64 vector_64_{};
//__m128i vector_128_{};
//__m256i vector_256_{};

//TODO Generate automatically?
Vector(__m128i vector) : vector_128_(vector)
Vector(__m64 vector) : vector_64_(vector)
{
}

/*Vector(__m128i vector) : vector_128_(vector)
{
}
Vector(__m256i vector) : vector_256_(vector)
{
}
}*/

public:
// Constructors
Expand All @@ -35,8 +40,6 @@ class Vector
{
}

Vector<T, X> static Blend(Vector<T, X> comparision, Vector<T, X> falseValue, Vector<T, X> trueValue);

// Assignment Operators
Vector<T, X>& operator+=(const Vector<T, X>& rhs);

Expand All @@ -45,36 +48,20 @@ class Vector
};

//TODO Move into struct?
#pragma region Vector<int32_t, 128>
// Constructors
template <> Vector<int32_t, 128>::Vector(int32_t value);
template <> Vector<int32_t, 128>::Vector(std::array<int32_t, 4> values);

std::ostream& operator<<(std::ostream& stream, const Vector<int32_t, 128>& vector);

Vector<int32_t, 128> Blend(Vector<int32_t, 128> comparision, Vector<int32_t, 128> falseValue, Vector<int32_t, 128> trueValue);

// Assignment Operators
template <> Vector<int32_t, 128>& Vector<int32_t, 128>::operator+=(const Vector<int32_t, 128>& rhs);

// Comparision Operators
template <> Vector<int32_t, 128> Vector<int32_t, 128>::operator>(const Vector<int32_t, 128>& vector2) const;
#pragma endregion

#pragma region Vector<int32_t, 256>
#pragma region Vector<int8_t, 64>
// Constructors
template <> Vector<int32_t, 256>::Vector(int32_t value);
template <> Vector<int32_t, 256>::Vector(std::array<int32_t, 8> values);
template <> Vector<int8_t, 64>::Vector(int8_t value);
template <> Vector<int8_t, 64>::Vector(std::array<int8_t, 8> values);

std::ostream& operator<<(std::ostream& stream, const Vector<int32_t, 256>& vector);
std::ostream& operator<<(std::ostream& stream, const Vector<int8_t, 64>& vector);

Vector<int32_t, 256> Blend(Vector<int32_t, 256> comparision, Vector<int32_t, 256> falseValue, Vector<int32_t, 256> trueValue);
//Vector<int8_t, 64> Blend(Vector<int8_t, 64> comparision, Vector<int8_t, 64> falseValue, Vector<int8_t, 64> trueValue);

// Assignment Operators
template <> Vector<int32_t, 256>& Vector<int32_t, 256>::operator+=(const Vector<int32_t, 256>& rhs);
template <> Vector<int8_t, 64>& Vector<int8_t, 64>::operator+=(const Vector<int8_t, 64>& rhs);

// Comparision Operators
template <> Vector<int32_t, 256> Vector<int32_t, 256>::operator>(const Vector<int32_t, 256>& vector2) const;
template <> Vector<int8_t, 64> Vector<int8_t, 64>::operator>(const Vector<int8_t, 64>& vector2) const;
#pragma endregion

#endif //VECTOR_H
21 changes: 12 additions & 9 deletions Vectors/Vector.h.tt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<#@ output extension="" #>
//TODO Merge string info arrays into a single structure
//TODO Automate generation of typeVectorConstructorArguments
<# var typeSizes = new int[] {32};
var vectorSizes = new int[] {128, 256}; #>
<# var typeSizes = new int[] {8};
var vectorSizes = new int[] {64}; #>
#ifndef VECTOR_H
#define VECTOR_H
#include <array>
Expand All @@ -16,17 +16,22 @@ class Vector
{
friend struct VectorHelpers;

__m128i vector_128_{};
__m256i vector_256_{};
__m64 vector_64_{};
//__m128i vector_128_{};
//__m256i vector_256_{};

//TODO Generate automatically?
Vector(__m128i vector) : vector_128_(vector)
Vector(__m64 vector) : vector_64_(vector)
{
}

/*Vector(__m128i vector) : vector_128_(vector)
{
}

Vector(__m256i vector) : vector_256_(vector)
{
}
}*/

public:
// Constructors
Expand All @@ -39,8 +44,6 @@ public:
{
}

Vector<T, X> static Blend(Vector<T, X> comparision, Vector<T, X> falseValue, Vector<T, X> trueValue);

// Assignment Operators
Vector<T, X>& operator+=(const Vector<T, X>& rhs);

Expand Down Expand Up @@ -68,7 +71,7 @@ template <> <#= typeVectorName #>::Vector(std::array<<#= typeName#>, <#= vectorS

std::ostream& operator<<(std::ostream& stream, const <#= typeVectorName #>& vector);

<#= typeVectorName #> Blend(<#= typeVectorName #> comparision, <#= typeVectorName #> falseValue, <#= typeVectorName #> trueValue);
//<#= typeVectorName #> Blend(<#= typeVectorName #> comparision, <#= typeVectorName #> falseValue, <#= typeVectorName #> trueValue);

// Assignment Operators
template <> <#= typeVectorName #>& <#= typeVectorName #>::operator+=(const <#= typeVectorName #>& rhs);
Expand Down

0 comments on commit 1f4c242

Please sign in to comment.