OpenCores
URL https://opencores.org/ocsvn/tanhapprox/tanhapprox/trunk

Subversion Repositories tanhapprox

[/] [tanhapprox/] [trunk/] [ann.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 psant064
#include <stdlib.h>
2
#include <stdio.h>
3
#include <math.h>
4
#include "ann.h"
5
#include "Data.h"
6
// include definitions for performance counter and custom instruction
7
#include "altera_avalon_performance_counter.h"
8
#include "system.h"
9
 
10
// debug options
11
#define PRINT_RESULTS    1
12
#define ACCELERATED_TANH 0
13
#define ACCELERATED_FLOATING_POINT 1
14
 
15
#if ACCELERATED_FLOATING_POINT == 0
16
#pragma no_custom_fadds
17
#pragma no_custom_fsubs
18
#pragma no_custom_fmuls
19
#pragma no_custom_fdivs
20
#endif // ACCELERATED_FLOATING_POINT == 0
21
 
22
#if ACCELERATED_TANH != 0
23
#define ALT_F_LOGSIG_APPROX_INST(A) __builtin_custom_fnf(ALT_CI_LOGSIG_APPROX_INST_N,(A))
24
#endif // ACCELERATED_TANH != 0
25
 
26
float aOutput[DATA_LENGTH][DATA_WIDTH];
27
 
28
void PrintArray(float *aIn, int nLength)
29
{
30
        int nIndex;
31
 
32
    printf("\n");
33
        for (nIndex = 0; nIndex < nLength; nIndex++)
34
        {
35
                printf("%f ", aIn[nIndex]);
36
        }
37
        printf("\n");
38
}
39
 
40
int main()
41
{
42
        int nIndexCol, nIndexRow;
43
    float nMeanSquaredError = 0;
44
    float nCurrentError = 0;
45
 
46
        float aInputWeightsMultipliedByInput[DATA_WIDTH];
47
        float aIntermediate1[DATA_WIDTH];
48
 
49
        float aHiddenWeightsMultipliedByInt1[DATA_WIDTH];
50
        float aIntermediate2[DATA_WIDTH];
51
 
52
        float aOutputWeightsMultipliedByInt2[DATA_WIDTH];
53
 
54
    printf("Start: Tansig acceleration [%d], floating point unit [%d]\n", ACCELERATED_TANH, ACCELERATED_FLOATING_POINT );
55
 
56
    Normalize(aInput, DATA_LENGTH);
57
    ArrayFill(aOutput, DATA_LENGTH, 0);
58
 
59
    // start measuring time
60
    PERF_RESET (PERFORMANCE_COUNTER_0_BASE);            //Reset Performance Counters to 0
61
    PERF_START_MEASURING (PERFORMANCE_COUNTER_0_BASE);  //Start the Counter
62
    PERF_BEGIN (PERFORMANCE_COUNTER_0_BASE,2);          //Start the overhead counter
63
    PERF_BEGIN (PERFORMANCE_COUNTER_0_BASE,1);          //Start the Matrix Multiplication Counter
64
    PERF_END (PERFORMANCE_COUNTER_0_BASE,2);            //Stop the overhead counter
65
 
66
        for (nIndexCol = 0; nIndexCol < DATA_LENGTH; nIndexCol++)
67
        {
68
                MatrixMultiplication(aInputWeights, aInput[nIndexCol], aInputWeightsMultipliedByInput, false);
69
                MatrixAddition(aInputWeightsMultipliedByInput, aInputBias, aIntermediate1);
70
                ArrayTanh(aIntermediate1);
71
 
72
                MatrixMultiplication(aHiddenWeights, aIntermediate1, aHiddenWeightsMultipliedByInt1, false);
73
                MatrixAddition(aHiddenWeightsMultipliedByInt1, aHiddenBias, aIntermediate2);
74
                ArrayTanh(aIntermediate2);
75
 
76
                MatrixMultiplication(aOutputWeights, aIntermediate2, aOutputWeightsMultipliedByInt2, false);
77
                MatrixAddition(aOutputWeightsMultipliedByInt2, aOutputBias, aOutput[nIndexCol]);
78
        }
79
 
80
    PERF_END (PERFORMANCE_COUNTER_0_BASE,1);            //Stop the Matrix Multiplication Counter
81
    PERF_STOP_MEASURING (PERFORMANCE_COUNTER_0_BASE);   //Stop all counters  
82
    perf_print_formatted_report((void *)PERFORMANCE_COUNTER_0_BASE, ALT_CPU_FREQ, 2,
83
    "ANN Calcs","PC overhead");
84
 
85
 
86
        Unnormalize(aOutput, DATA_LENGTH);
87
 
88
#if PRINT_RESULTS != 0
89
        // Print results
90
        printf("Results\n");
91
        for (nIndexCol = 0; nIndexCol < DATA_LENGTH; nIndexCol++)
92
        {
93
                // print only the first 3 columns of result matrix (as result is a Nx3 matrix)
94
        printf("%f %f %f\n", aOutput[nIndexCol][0], aOutput[nIndexCol][1], aOutput[nIndexCol][2] );
95
        }
96
#endif // PRINT_RESULTS != 0
97
 
98
        for (nIndexCol = 0; nIndexCol < DATA_LENGTH; nIndexCol++)
99
        {
100
                for (nIndexRow = 0; nIndexRow < (DATA_WIDTH - 1); nIndexRow++)
101
                {
102
                        nCurrentError           = aOutput[nIndexCol][nIndexRow] - aExpectedResults[nIndexCol][nIndexRow];
103
                        nMeanSquaredError       += nCurrentError * nCurrentError;
104
                }
105
        }
106
 
107
        nMeanSquaredError = nMeanSquaredError / (DATA_LENGTH * (DATA_WIDTH - 1));
108
 
109
        printf("Mean Squared Error: %f", nMeanSquaredError);
110
 
111
        system("PAUSE");
112
}
113
 
114
 
115
void ArrayFill(float aInput[DATA_LENGTH][DATA_WIDTH], int nCountCol, float nValueToFill)
116
{
117
        int nIndexCol, nIndexRow;
118
    for (nIndexCol = 0; nIndexCol < nCountCol; nIndexCol++)
119
        {
120
                for (nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
121
                {
122
                        aInput[nIndexCol][nIndexRow] = nValueToFill;
123
                }
124
        }
125
}
126
 
127
 
128
void ArrayTanh(float aInput[DATA_WIDTH])
129
{
130
        int nIndexRow;
131
    for (nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
132
        {
133
        // choose between accelerated and non-accelerated tangent sigmoid
134
#if ACCELERATED_TANH == 0
135
        // non-accelerated (calculate with math.h)
136
                aInput[nIndexRow] = tanhf(aInput[nIndexRow]);
137
#else
138
        // accelerated (estimate with dedicated look-up table)
139
        aInput[nIndexRow] = ALT_F_LOGSIG_APPROX_INST(aInput[nIndexRow]);
140
#endif
141
        }
142
}
143
 
144
 
145
// Multiplies a 4x4 matrix by a 4x1
146
void MatrixMultiplication(float aMatrix1[DATA_WIDTH][DATA_WIDTH], float aMatrix2[DATA_WIDTH], float aOutput[DATA_WIDTH], char bPrintResults)
147
{
148
        int nIndexRow, nIndexCol;
149
    if (bPrintResults == true) printf("beginning matrix multiplication\n");
150
        // Init Output to 0's
151
        for (nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
152
        {
153
                aOutput[nIndexRow] = 0;
154
        }
155
 
156
        for (nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
157
        {
158
                for (nIndexCol = 0; nIndexCol < DATA_WIDTH; nIndexCol++)
159
                {
160
                        if (bPrintResults == true) printf("%f * %f\n",aMatrix1[nIndexRow][nIndexCol],aMatrix2[nIndexCol]);
161
                        aOutput[nIndexRow] += aMatrix1[nIndexRow][nIndexCol] * aMatrix2[nIndexCol];
162
                }
163
        }
164
}
165
 
166
// Adds two 4x1 matrices
167
void MatrixAddition(float aMatrix1[DATA_WIDTH], float aMatrix2[DATA_WIDTH], float aOutput[DATA_WIDTH])
168
{
169
        int nIndexRow;
170
    for (nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
171
        {
172
                aOutput[nIndexRow] = aMatrix1[nIndexRow] + aMatrix2[nIndexRow];
173
        }
174
}
175
 
176
 
177
// Normalizes matrix entries from -1 to 1
178
void Normalize(float aInput[DATA_LENGTH][DATA_WIDTH], int nCountCol)
179
{
180
        float aMin[DATA_WIDTH];
181
        float aMax[DATA_WIDTH];
182
        float nCurrentCell;
183
    int nIndexRow, nIndexCol;
184
 
185
        // First find min and max
186
        for ( nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++ )
187
        {
188
                aMin[nIndexRow] = 9999999; // HACK!!
189
                aMax[nIndexRow] = 0;
190
                for ( nIndexCol = 0; nIndexCol < nCountCol; nIndexCol++ )
191
                {
192
                        nCurrentCell = aInput[nIndexCol][nIndexRow];
193
                        if (nCurrentCell < aMin[nIndexRow]) aMin[nIndexRow] = nCurrentCell;
194
                        if (nCurrentCell > aMax[nIndexRow]) aMax[nIndexRow] = nCurrentCell;
195
                }
196
        }
197
 
198
 
199
        // Normalize
200
        for ( nIndexCol = 0; nIndexCol < nCountCol; nIndexCol++)
201
        {
202
                for ( nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
203
                {
204
                        nCurrentCell                                    = aInput[nIndexCol][nIndexRow];
205
                        aInput[nIndexCol][nIndexRow]    = (((nCurrentCell - aMin[nIndexRow]) / (aMax[nIndexRow] - aMin[nIndexRow])) * 2) - 1;
206
                }
207
        }
208
}
209
 
210
// "Un-normalizes matrix"
211
void Unnormalize(float aInput[][DATA_WIDTH], int nCountCol)
212
{
213
        int nIndexCol, nIndexRow;
214
    for ( nIndexCol = 0; nIndexCol < nCountCol; nIndexCol++)
215
        {
216
                for ( nIndexRow = 0; nIndexRow < DATA_WIDTH; nIndexRow++)
217
                {
218
                        aInput[nIndexCol][nIndexRow] = (aInput[nIndexCol][nIndexRow] + 1) / 2;
219
                }
220
        }
221
}
222
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.