Skip to content
Snippets Groups Projects
Commit 88938969 authored by Nermine Ali's avatar Nermine Ali
Browse files

adds generation and conversion functions from cpp export

parent c2201433
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,7 @@
template<typename Output_T, typename T,
typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
__attribute__((always_inline)) inline
Output_T saturate (T value, int32_t sat)
Output_T saturate (T value, int32_t /*sat*/)
{
return value;
}
......@@ -49,6 +49,10 @@ Output_T activation_forward_value (Sum_T weightedSum,
break;
}
// Value fixed here for now, but it should be generated by
// the export module or determined by the type of Output_T
// For now it only works for int8_t and uint8_t
const uint32_t NB_BITS = 8;
return saturate<Output_T>(rescaling(weightedSum, output), NB_BITS);
}
......
......@@ -3,6 +3,8 @@
#include "network/typedefs.hpp"
#include "network/utils.hpp"
#include <limits>
#include <stdexcept>
template<int NB_CHANNELS,
......@@ -84,7 +86,7 @@ void pooling_forward(
outputs[oOffset + output] = maxVal;
}
else if (POOLING_TYPE == Average) {
SUM_T sum = 0;
int32_t sum = 0;
for (int sy = 0; sy < POOL_HEIGHT; ++sy) {
if ((PADDING_Y != 0
......@@ -114,7 +116,7 @@ void pooling_forward(
outputs[oOffset + output] = (Output_T) (sum / (POOL_HEIGHT * POOL_WIDTH));
}
else {
throw(std::runtime_error, "The export only supports Max and Average pooling.");
throw std::runtime_error("The export only supports Max and Average pooling.");
}
}
}
......
#ifndef __AIDGE_EXPORT_CPP_NETWORK_RESCALING__
#define __AIDGE_EXPORT_CPP_NETWORK_RESCALING__
// For this demo
#define SUM_T float
#define NB_BITS -32
struct NoScaling {
SUM_T operator()(SUM_T weightedSum, unsigned int /*output*/) const {
template<typename Sum_T>
Sum_T operator()(Sum_T weightedSum, unsigned int /*output*/) const
{
return weightedSum;
}
};
......
......@@ -5,6 +5,8 @@
int main()
{
// Example for MNIST dataset
// Feel free to change this file for your own projects
const unsigned int nb_classes = 10;
float results[nb_classes];
......
......@@ -4,9 +4,13 @@
#define MEMORY_SIZE {{ mem_size }}
{% for offset in offsets %}
#define {{ offset }}
{% for i in range(mem_info|length) -%}
{%- set layer_name = mem_info[i][0] %}
/* {{layer_name}} memory */
{% for j in range(1, mem_info[i]|length) %}
#define {{ layer_name|upper }}_{{ mem_info_legends[j]|upper }} {{ mem_info[i][j] }}
{%- endfor %}
{% endfor %}
#endif /* MEM_INFO_H */
\ No newline at end of file
......@@ -23,3 +23,21 @@ void CCS_BLOCK(model_forward)(ac_sync &start, const {{input_t}}* {{inputs}}, {{o
}
private:
mem_in<{{name|upper}}_NB_CHANNELS,
{{name|upper}}_CHANNELS_HEIGHT,
{{name|upper}}_CHANNELS_WIDTH,
{{name|upper}}_OUTPUTS_HEIGHT,
{{name|upper}}_OUTPUTS_WIDTH,
{{name|upper}}_PADDING_Y,
{{name|upper}}_PADDING_X,
{{name|upper}}_STRIDE_Y,
{{name|upper}}_STRIDE_X,
{{name|upper}}_KERNEL_HEIGHT,
{{name|upper}}_KERNEL_WIDTH,
{{name|upper}}_ACTIVATION,
DATA_T,
{{child_name|upper}}_in_t> {# it's the name of the next layer not the current one #}
mem_in_inst;
{# Need to add all transitions between layers below #}
from pathlib import Path
import os
# Constants
FILE = Path(__file__).resolve()
ROOT = FILE.parents[1]
OPERATORS_REGISTRY = {}
def operator_register(*args):
key_list = [arg for arg in args]
def decorator(operator):
class Wrapper(operator):
def __init__(self, *args, **kwargs):
return operator(*args, **kwargs)
for key in key_list:
OPERATORS_REGISTRY[key] = operator
return Wrapper
return decorator
def supported_operators():
return list(OPERATORS_REGISTRY.keys())
import numpy as np
import aidge_core
def numpy_dtype2ctype(dtype):
if dtype == np.int8:
return "int8_t"
elif dtype == np.int16:
return "int16_t"
elif dtype == np.int32:
return "int32_t"
elif dtype == np.int64:
return "int64_t"
elif dtype == np.float32:
return "float"
elif dtype == np.float64:
return "double"
# Add more dtype mappings as needed
else:
raise ValueError(f"Unsupported {dtype} dtype")
def aidge_datatype2ctype(datatype):
if datatype == aidge_core.DataType.Int8:
return "int8_t"
elif datatype == aidge_core.DataType.Int32:
return "int32_t"
elif datatype == aidge_core.DataType.Int64:
return "int64_t"
elif datatype == aidge_core.DataType.Float32:
return "float"
elif datatype == aidge_core.DataType.Float64:
return "double"
# Add more dtype mappings as needed
else:
raise ValueError(f"Unsupported {datatype} aidge datatype")
\ No newline at end of file
import re
import os
import shutil
from jinja2 import Environment, FileSystemLoader
def get_functions_from_c_file(file_path):
functions = []
pattern = r'\w+\s+(\w+)\s*\(([^)]*)\)\s*{'
with open(file_path, 'r') as file:
file_content = file.read()
matches = re.findall(pattern, file_content)
for match in matches:
function_name = match[0]
arguments = match[1].split(',')
arguments = [arg.strip() for arg in arguments]
return_type = get_return_type(file_content, function_name)
function_string = f"{return_type} {function_name}({', '.join(arguments)});"
functions.append(function_string)
return functions
def get_return_type(file_content, function_name):
pattern = rf'\w+\s+{function_name}\s*\([^)]*\)\s*{{'
return_type = re.search(pattern, file_content).group()
return_type = return_type.split()[0].strip()
return return_type
def get_functions_from_c_folder(folder_path):
functions = []
for _, _, files in os.walk(folder_path):
for file in files:
functions += get_functions_from_c_file(os.path.join(folder_path, file))
return functions
def copyfile(filename, dst_folder):
# If directory doesn't exist, create it
if not os.path.exists(dst_folder):
os.makedirs(dst_folder)
shutil.copy(filename, dst_folder)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment