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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ jobs:
run: cmake --build --preset unit_test

- name: Test
run: ctest --preset unit_test
run: ctest --preset unit_test --exclude-regex UnitTestDataLoader
4 changes: 3 additions & 1 deletion src/arithmetic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_library(Distributions Distributions.c)
target_include_directories(Distributions PUBLIC include)
target_link_libraries(Distributions PRIVATE
Common
RNG
m
)

Expand Down Expand Up @@ -86,8 +87,9 @@ add_library(Rounding Rounding.c)
target_include_directories(Rounding PUBLIC include)
target_link_libraries(Rounding PRIVATE
m
RNG
Common
)#include "Common.h"
)


add_library(Square Square.c)
Expand Down
13 changes: 6 additions & 7 deletions src/arithmetic/Distributions.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
#define SOURCE_FILE "DISTRIBUTIONS"

#include <math.h>
#include <stdlib.h>

#include "Distributions.h"
#include "math.h"
#include "RNG.h"


float randomNormal(float mean, float standardDeviation) {
float u1 = (float)rand() / RAND_MAX;
float u2 = (float)rand() / RAND_MAX;
float u1 = rngNextFloat();
float u2 = rngNextFloat();

// Avoid log(0)
while (u1 <= 1e-7f) {
u1 = (float)rand() / RAND_MAX;
u1 = rngNextFloat();
}

float z = sqrtf(-2.0f * logf(u1)) * cosf(2.0f * M_PI * u2);
float z = sqrtf(-2.0f * logf(u1)) * cosf(2.0f * (float)M_PI * u2);
return mean + standardDeviation * z;
}

float randomUniform(float min, float max) {
float r = (float)rand() / RAND_MAX;
float r = rngNextFloat();
return min + r * (max - min);
}

Expand Down
4 changes: 2 additions & 2 deletions src/arithmetic/Rounding.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#define SOURCE_FILE "ROUNDING"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "Rounding.h"
#include "RNG.h"


// round to even, when fractional is EXACTLY 0.5
Expand All @@ -13,7 +13,7 @@ int32_t roundHTE(float input) {
}

float randfloat() {
return (float)rand() / ((float)RAND_MAX + 1);
return rngNextFloat();
}

int32_t roundSRHTE(const float input) {
Expand Down
12 changes: 4 additions & 8 deletions src/common/include/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@
#define SOURCE_FILE "no Source file defined!"
#endif

#define DLEVEL 0

#ifdef DEBUG_MODE_DEBUG
#define DLEVEL 3
#endif

#ifdef DEBUG_MODE_INFO
#elif defined(DEBUG_MODE_INFO)
#define DLEVEL 2
#endif

#ifdef DEBUG_MODE_ERROR
#elif defined(DEBUG_MODE_ERROR)
#define DLEVEL 1
#else
#define DLEVEL 0
#endif

#define PRINT_DEBUG(str, ...) \
Expand Down
3 changes: 2 additions & 1 deletion src/data_loader/DataLoader.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ void initDataLoader(dataLoader_t *dataLoader, getSampleFn_t getSample,
indices[i] = i;

if (shuffle) {
rngShuffleIndices(indices, numberOfIndices, shuffleSeed);
rngSetSeed(shuffleSeed);
rngShuffleIndices(indices, numberOfIndices);
}
}

Expand Down
60 changes: 17 additions & 43 deletions src/layer/Softmax.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,32 +113,18 @@ void softmaxForward(layer_t *softmaxLayer, tensor_t *input, tensor_t *output) {
}

static void softmaxBackwardFloat(tensor_t *input, tensor_t *loss, tensor_t *propLoss) {
size_t n = calcNumberOfElementsByTensor(input);

size_t inputSize = calcNumberOfElementsByTensor(input);

float *inputFloat = (float *)input->data;
float *lossFloat = (float *)loss->data;
float *propLossFloat = (float *)propLoss->data;

float jacobian[inputSize][inputSize];
float *s = (float *)input->data;
float *dLds = (float *)loss->data;
float *dLdx = (float *)propLoss->data;

for (size_t i = 0; i < inputSize; i++) {
for (size_t j = 0; j < inputSize; j++) {
if (i == j) {
jacobian[i][j] = inputFloat[i] * (1 - inputFloat[i]);
} else {
jacobian[i][j] = -inputFloat[i] * inputFloat[j];
}
}
}
float dot = 0.0f;
for (size_t i = 0; i < n; i++)
dot += s[i] * dLds[i];

for (size_t i = 0; i < inputSize; i++) {
float sum = 0;
for (size_t j = 0; j < inputSize; j++) {
sum += jacobian[i][j] * lossFloat[j];
}
propLossFloat[i] = sum;
}
for (size_t i = 0; i < n; i++)
dLdx[i] = s[i] * (dLds[i] - dot);
}

static void softmaxBackwardSymInt32(tensor_t *input, tensor_t *loss, tensor_t *propLoss) {
Expand All @@ -165,29 +151,17 @@ static void softmaxBackwardSymInt32(tensor_t *input, tensor_t *loss, tensor_t *p
setTensorValuesForConversion(propLossFloatData, &propLossFloatQ, propLoss, &propLossFloat);
convertTensor(propLoss, &propLossFloat);

float *inputFloatArr = (float *)inputFloat.data;
float *lossFloatArr = (float *)lossFloat.data;
float *propLossFloatArr = (float *)propLossFloat.data;
float *s = (float *)inputFloat.data;
float *dLds = (float *)lossFloat.data;
float *dLdx = (float *)propLossFloat.data;

float jacobian[inputSize][inputSize];
float dot = 0.0f;
for (size_t i = 0; i < inputSize; i++)
dot += s[i] * dLds[i];

for (size_t i = 0; i < inputSize; i++) {
for (size_t j = 0; j < inputSize; j++) {
if (i == j) {
jacobian[i][j] = inputFloatArr[i] * (1 - inputFloatArr[i]);
} else {
jacobian[i][j] = -inputFloatArr[i] * inputFloatArr[j];
}
}
}
for (size_t i = 0; i < inputSize; i++)
dLdx[i] = s[i] * (dLds[i] - dot);

for (size_t i = 0; i < inputSize; i++) {
float sum = 0;
for (size_t j = 0; j < inputSize; j++) {
sum += jacobian[i][j] * lossFloatArr[j];
}
propLossFloatArr[i] = sum;
}
convertTensor(&propLossFloat, propLoss);
}

Expand Down
14 changes: 8 additions & 6 deletions src/rng/RNG.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "RNG.h"


static rng32_t rng;
static rng32_t rng = {.state = 1};

static uint32_t rngNext(rng32_t *rng)
{
Expand All @@ -27,12 +27,10 @@ static size_t rngBounded(rng32_t *rng, size_t bound)
return x % bound;
}

void rngShuffleIndices(size_t *indices, size_t n, uint32_t seed)
void rngShuffleIndices(size_t *indices, size_t n)
{
if (n < 2) return;

rng32_t rng = { .state = seed ? seed : 1 };

for (size_t i = n - 1; i > 0; --i) {
size_t j = rngBounded(&rng, i + 1);

Expand All @@ -43,9 +41,13 @@ void rngShuffleIndices(size_t *indices, size_t n, uint32_t seed)
}

void rngSetSeed(uint32_t seed) {
rng.state = seed;
rng.state = seed ? seed : 1;
}

uint32_t rngGetSeed() {
uint32_t rngGetSeed(void) {
return rng.state;
}

float rngNextFloat(void) {
return (float)(rngNext(&rng) >> 8) / (float)(1 << 24);
}
9 changes: 7 additions & 2 deletions src/rng/include/RNG.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ typedef struct {
uint32_t state;
} rng32_t;

void rngShuffleIndices(size_t *indices, size_t n, uint32_t seed);
// NOTE: not thread-safe — all functions below use module-global RNG state.
// When multi-threading support is added, migrate to context-passing variants.

void rngShuffleIndices(size_t *indices, size_t n);

void rngSetSeed(uint32_t seed);

uint32_t rngGetSeed();
uint32_t rngGetSeed(void);

float rngNextFloat(void);

#endif //RNG_H
1 change: 1 addition & 0 deletions src/userApi/layer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_library(LinearApi LinearApi.c)
target_include_directories(LinearApi PUBLIC include)
target_link_libraries(LinearApi PRIVATE
Tensor
TensorApi
Rounding
Layer
Linear
Expand Down
7 changes: 3 additions & 4 deletions src/userApi/layer/LinearApi.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Layer.h"
#include "Tensor.h"
#include "StorageApi.h"
#include "TensorApi.h"
#include "LinearApi.h"
#include "Linear.h"

Expand Down Expand Up @@ -38,10 +39,8 @@ layer_t *linearLayerInitNonTrainable(tensor_t *weights, tensor_t *bias, quantiza
linearConfig_t *linearConfig = *reserveMemory(sizeof(linearConfig_t));
layerConfig->linear = linearConfig;

linearConfig->weights->param = weights;
linearConfig->weights->grad = NULL;
linearConfig->bias->param = bias;
linearConfig->bias->grad = NULL;
linearConfig->weights = parameterInit(weights, NULL);
linearConfig->bias = parameterInit(bias, NULL);
linearConfig->forwardQ = forwardQ;

linearLayer->config = layerConfig;
Expand Down
20 changes: 9 additions & 11 deletions src/userApi/tensor/TensorApi.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ tensor_t *tensorInitWithDistribution(distributionType_t distributionType, float
memset(data, 0, numberOfValues * sizeof(float));
break;
case ONES:
memset(data, 1, numberOfValues * sizeof(float));
for (size_t i = 0; i < numberOfValues; i++) {
data[i] = 1.0f;
}
break;
case NORMAL:
for (size_t i = 0; i < numberOfValues; i++) {
Expand All @@ -106,27 +108,23 @@ tensor_t *tensorInitWithDistribution(distributionType_t distributionType, float
}
break;
case XAVIER_NORMAL:
float xavierStd = sqrtf(6.0f / (float)(inputFeatures + outputFeatures));
for (size_t i = 0; i < numberOfValues; i++) {
data[i] = randomNormal(0.0f, xavierStd);
data[i] = xavierNormal(1.0f, inputFeatures, outputFeatures);
}
break;
case XAVIER_UNIFORM:
float xavierLimit = sqrtf(6.0f / (float)(inputFeatures + outputFeatures));
for (size_t i = 0; i < numberOfValues; i++) {
data[i] = randomUniform(-xavierLimit, xavierLimit);
data[i] = xavierUniform(1.0f, inputFeatures, outputFeatures);
}
break;
case HE_NORMAL:
float heStd = sqrtf(2.0f / (float)inputFeatures);
case KAIMING_NORMAL:
for (size_t i = 0; i < numberOfValues; i++) {
data[i] = randomNormal(0.0f, heStd);
data[i] = kaimingNormal(sqrtf(2.0f), inputFeatures);
}
break;
case HE_UNIFORM:
float heLimit = sqrtf(2.0f / (float)inputFeatures);
case KAIMING_UNIFORM:
for (size_t i = 0; i < numberOfValues; i++) {
data[i] = randomNormal(-heLimit, heLimit);
data[i] = kaimingUniform(sqrtf(2.0f), inputFeatures);
}
break;
default:
Expand Down
1 change: 1 addition & 0 deletions test/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_subdirectory(data_loader)
add_subdirectory(layer)
add_subdirectory(loss_functions)
add_subdirectory(optimizer)
add_subdirectory(rng)
add_subdirectory(serial)
add_subdirectory(tensor)
add_subdirectory(userAPI)
Expand Down
1 change: 1 addition & 0 deletions test/unit/arithmetic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_elastic_ai_unit_test(
Distributions
MORE_LIBS
MinMax
RNG
Common
)

Expand Down
Loading
Loading