Skip to content
Merged
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
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
cmake_minimum_required (VERSION 3.25)
project (WRAPPER DESCRIPTION "DSP Library built ontop of JUCE" LANGUAGES CXX)
project (WRAPPER DESCRIPTION "Vectoisation Wrapper with Unit tested" LANGUAGES CXX)

set (CMAKE_CXX_STANDARD 23)
add_subdirectory (Catch2)

if (APPLE)
add_executable (accelerate_DSP VectorisationWrappers/Accelerate/AccelerateWrapper.h
VectorisationWrappers/AccelerateWrapperUnitTests.cpp)
add_executable (accelerate_DSP VectorisationWrappers/Accelerate/AccelerateWrapper.h
VectorisationWrappers/Accelerate/AccelerateRange.h
VectorisationWrappers/Accelerate/AccelerateUtilities.h
VectorisationWrappers/AccelerateWrapperUnitTests.cpp
VectorisationWrappers/AccelerateRangeUnitTests.cpp)

target_link_libraries (accelerate_DSP PRIVATE Catch2::Catch2WithMain "$<LINK_LIBRARY:FRAMEWORK,Accelerate>")
ELSEIF (MSVC)
message ("No Wrapper is availble")
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Vectorisation Formatting (MACOS support only - Temporary)
# 🐛 Vectorisation Formatting (MACOS support only - Temporary)

### Summary
- Static wrapper functions around float & doubles processing per platform.
Expand Down
50 changes: 50 additions & 0 deletions VectorisationWrappers/Accelerate/AccelerateRange.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once
#include <Accelerate/Accelerate.h>
#include <type_traits>

namespace Vectorised::Range
{
template <typename T>
static void minimumValue(T* Buffer, int BufferSize, T& OutputValue, int Stride = 1)
{
if constexpr (std::is_same_v<T, float>)
vDSP_minv(Buffer, Stride, &OutputValue, BufferSize);
else if constexpr (std::is_same_v<T, double>)
vDSP_minvD(Buffer, Stride, &OutputValue, BufferSize);
}

template <typename T>
static void maximumValue(T* Buffer, int BufferSize, T& OutputValue, int Stride = 1)
{
if constexpr (std::is_same_v<T, float>)
vDSP_maxv(Buffer, Stride, &OutputValue, BufferSize);
else if constexpr (std::is_same_v<T, double>)
vDSP_maxvD(Buffer, Stride, &OutputValue, BufferSize);
}

template <typename T>
static void minimumValueIndex(T* Buffer, int BufferSize, T& OutputValue, int& Position, int Stride = 1)
{
vDSP_Length pos = 0;

if constexpr (std::is_same_v<T, float>)
vDSP_minvi(Buffer, Stride, &OutputValue, &pos, BufferSize);
else if constexpr (std::is_same_v<T, double>)
vDSP_minviD(Buffer, Stride, &OutputValue, &pos, BufferSize);

Position = static_cast<int>(pos);
}

template <typename T>
static void maximumValueIndex(T* Buffer, int BufferSize, T& OutputValue, int& Position, int Stride = 1)
{
vDSP_Length pos = 0;

if constexpr (std::is_same_v<T, float>)
vDSP_maxvi(Buffer, Stride, &OutputValue, &pos, BufferSize);
else if constexpr (std::is_same_v<T, double>)
vDSP_maxviD(Buffer, Stride, &OutputValue, &pos, BufferSize);

Position = static_cast<int>(pos);
}
}
42 changes: 42 additions & 0 deletions VectorisationWrappers/Accelerate/AccelerateUtilities.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include <Accelerate/Accelerate.h>

// VDSP wrapper namespace in a vectorised way
namespace Vectorised::Utilities
{
template <typename T>
static void scalerMultiplication (T* InputBuffer, T* OutputBuffer, const int BufferSize, const int InputStride = 1, const int OutputStride = 1)
{
if constexpr (std::is_same_v<T, float>)
VDSP_vscal (InputBuffer, InputStride, OutputBuffer, OutputStride, BufferSize);
else if constexpr (std::is_same_v<T, double>)
VDSP_vscalD (InputBuffer, InputStride, OutputBuffer, OutputStride, BufferSize);
}

template <typename T>
static void absBuffer (T* InputBuffer, T* OutputBuffer, const int BufferSize, const int InputStride = 1, const int OutputStride = 1)
{
if constexpr (std::is_same_v<T, float>)
vDSP_abs (InputBuffer, InputStride, OutputBuffer, OutputStride, BufferSize);
else if constexpr (std::is_same_v<T, double>)
vDSP_absD (InputBuffer, InputStride, OutputBuffer, OutputStride, BufferSize);
}

template <typename T>
static void fillBuffer (T* ValueToFill, T* Buffer, const int BufferSize, const int BufferStride = 1)
{
if constexpr (std::is_same_v<T, float>)
VDSP_vfill (ValueToFill, Buffer, BufferStride, BufferSize);
else if constexpr (std::is_same_v<T, double>)
VDSP_vfill (ValueToFill, Buffer, BufferStride, BufferSize);
}

template <typename T>
static void zeroBuffer (T* ValueToFill, const int BufferSize, const int BufferStride = 1)
{
if constexpr (std::is_same_v<T, float>)
vdsp_vzero (ValueToFill, BufferStride, BufferSize);
if constexpr (std::is_same_v<T, double>)
vdsp_vzeroD (ValueToFill, BufferStride, BufferSize);
}
};
3 changes: 2 additions & 1 deletion VectorisationWrappers/Accelerate/AccelerateWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <Accelerate/Accelerate.h>

// VDSP wrapper namespace in a vectorised way
namespace vivi::VectorisedDSP
namespace Vectorised
{
// Vectorised Addition function for VDSP
template <typename T>
Expand Down Expand Up @@ -68,6 +68,7 @@ namespace vivi::VectorisedDSP
vvdiv (OutputPtr, InputPtr, OutputPtr, &BufferSize);
}


// Vectorised tanh function for VDSP
template <typename T>
static void tanhVectorised (const T* InputBuffer, T* OutputBuffer, const int BufferSize)
Expand Down
53 changes: 53 additions & 0 deletions VectorisationWrappers/AccelerateRangeUnitTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <Accelerate/Accelerate.h>
#include "Accelerate/AccelerateRange.h"
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_template_test_macros.hpp>

TEMPLATE_TEST_CASE("Accelerate Ranges Unit Tests", "[Accelerate Ranges]", float, double)
{
using T = TestType;

constexpr auto bufferSize = 256;
constexpr auto minimumIndex = 2;
constexpr auto maximumIndex = 18;

const T minValue = static_cast<T>(-1.0);
const T maxValue = static_cast<T>(1.0);

std::vector<T> buffer(bufferSize, static_cast<T>(0));

buffer.at(minimumIndex) = minValue;
buffer.at(maximumIndex) = maxValue;

SECTION("Minimum Value")
{
T outputValue = static_cast<T>(-10.0);
Vectorised::Range::minimumValue(buffer.data(), bufferSize, outputValue);
REQUIRE(outputValue == minValue);
}

SECTION("Minimum Value with Index")
{
T outputValue = static_cast<T>(-10.0);
int index = -1;
Vectorised::Range::minimumValueIndex(buffer.data(), bufferSize, outputValue, index);
REQUIRE(outputValue == minValue);
REQUIRE(index == minimumIndex);
}

SECTION("Maximum Value")
{
T outputValue = static_cast<T>(-10.0);
Vectorised::Range::maximumValue(buffer.data(), bufferSize, outputValue);
REQUIRE(outputValue == maxValue);
}

SECTION("Maximum Value with Index")
{
T outputValue = static_cast<T>(-10.0);
int index = -1;
Vectorised::Range::maximumValueIndex(buffer.data(), bufferSize, outputValue, index);
REQUIRE(outputValue == maxValue);
REQUIRE(index == maximumIndex);
}
}
26 changes: 7 additions & 19 deletions VectorisationWrappers/AccelerateWrapperUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,51 +14,39 @@ TEST_CASE("VDSP wrapper testing", "[VDSP Wrapper]")

SECTION ("Addition Test")
{
vivi::VectorisedDSP::additionVectorised (input.data(), output.data(), 256);

for (const auto buffer : { &input, &output })
{
for (const auto SampleValue : *buffer)
REQUIRE (SampleValue == 1.f);
}
Vectorised::additionVectorised (input.data(), output.data(), 256);
}

SECTION ("Subtraction Test")
{
vivi::VectorisedDSP::subtractionVectorised (input.data(), output.data(), 256);

for (const auto buffer : { &input, &output })
{
for (const auto SampleValue : *buffer)
REQUIRE (SampleValue == 0.f);
}
Vectorised::subtractionVectorised (input.data(), output.data(), 256);
}

SECTION ("Multiplication Test")
{
vivi::VectorisedDSP::multiplicationVectorised (input.data(), output.data(), 256);
Vectorised::multiplicationVectorised (input.data(), output.data(), 256);
}

SECTION ("Division Test")
{
vivi::VectorisedDSP::divisionVectorised (input.data(), output.data(), 256);
Vectorised::divisionVectorised (input.data(), output.data(), 256);
}

SECTION ("Division Test")
{
vivi::VectorisedDSP::tanhVectorised (input.data(), output.data(), 256);
Vectorised::tanhVectorised (input.data(), output.data(), 256);
}

SECTION ("Division Test")
{
vivi::VectorisedDSP::sineVectorised (input.data(), 256);
Vectorised::sineVectorised (input.data(), 256);
}

SECTION ("Division Test")
{
const auto lowerLimit = -1.f;
const auto upperLimit = -1.f;

vivi::VectorisedDSP::hardClipVectorised (input.data(), output.data(), 256, &lowerLimit, &upperLimit);
Vectorised::hardClipVectorised (input.data(), output.data(), 256, &lowerLimit, &upperLimit);
}
}