Skip to content
Open
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/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
working-directory: ${{github.workspace}}/build
shell: bash
# Execute the build. You can specify a specific target with "--target <NAME>"
run: cmake --build . --config $BUILD_TYPE -- -j
run: cmake --build . --config $BUILD_TYPE

- name: Test
working-directory: ${{github.workspace}}/build
Expand Down
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ string(
add_compile_options("${_opts}")

option(USE_RUNTIME_CHECKS "Check arguments and emit warnings" OFF)
option(TRACK_STATISTICS "Tracks statistics such as register reads and energy use" ON)
option(TRACK_STATISTICS "Tracks statistics such as register reads and energy use" OFF)
option(USE_CUDA "Uses CUDA for GPU processing" ON)
if (USE_RUNTIME_CHECKS)
message(STATUS "With runtime checks")
add_definitions(-DUSE_RUNTIME_CHECKS)
Expand All @@ -29,6 +30,11 @@ if (TRACK_STATISTICS)
add_definitions(-DTRACK_STATISTICS)
endif ()
unset(TRACK_STATISTICS CACHE)
if (USE_CUDA)
message(STATUS "Using CUDA")
add_definitions(-DUSE_CUDA)
endif ()
unset(USE_CUDA CACHE)


IF (UNIX)
Expand All @@ -49,7 +55,7 @@ ENDIF ()
set(CONAN_SYSTEM_INCLUDES ON)
conan_basic_setup()

add_executable(${SIM_LIB} main.cpp src/simulator/registers/analogue_register.cpp include/simulator/registers/analogue_register.h src/simulator/registers/digital_register.cpp include/simulator/registers/digital_register.h src/simulator/buses/analogue_bus.cpp include/simulator/buses/analogue_bus.h src/simulator/buses/digital_bus.cpp include/simulator/buses/digital_bus.h src/simulator/base/pixel.cpp include/simulator/base/pixel.h src/simulator/base/architecture.cpp include/simulator/base/architecture.h src/simulator/pe/processing_element.cpp include/simulator/pe/processing_element.h src/simulator/units/comparator.cpp include/simulator/units/comparator.h src/simulator/units/squarer.cpp include/simulator/units/squarer.h src/simulator/registers/register.cpp include/simulator/registers/register.h src/simulator/base/component.cpp include/simulator/base/component.h src/simulator/memory/dram/dram3t_cell.cpp include/simulator/memory/dram3t_cell.h src/simulator/memory/sram/sram6t_cell.cpp include/simulator/memory/sram6t_cell.h src/simulator/memory/memory.cpp include/simulator/memory/memory.h src/simulator/memory/si/si_cell.cpp include/simulator/memory/si_cell.h src/simulator/util/utility.cpp include/simulator/util/utility.h src/simulator/metrics/cycle_counter.cpp include/simulator/metrics/cycle_counter.h src/simulator/metrics/json_writer.cpp include/simulator/metrics/json_writer.h include/simulator/ui/async_file_streamer.h include/simulator/ui/async_file_reader.h src/simulator/ui/ui.cpp include/simulator/ui/ui.h src/simulator/ui/file_watcher.cpp include/simulator/ui/file_watcher.h include/simulator/ui/base64_encoder.h src/simulator/ui/src/base64_encoder.cpp include/simulator/input/input_source.h src/simulator/input/live_input.cpp include/simulator/input/live_input.h src/simulator/input/image_input.cpp include/simulator/input/image_input.h src/simulator/input/video_input.cpp include/simulator/input/video_input.h include/simulator/base/plane_params.h src/simulator/base/plane_params.cpp include/simulator/adders/cla.h src/simulator/adders/cla.cpp include/simulator/base/config.h src/simulator/base/config.cpp include/simulator/metrics/stats_outputter.h src/simulator/memory/dram/dram_array.cpp include/simulator/memory/dram_array.h include/simulator/external/parser.h src/simulator/external/parser.cpp scamp5/scamp5.h scamp5/scamp5.cpp scamp5/analognet2/conv_instructions.h scamp5/analognet2/fc_weights.h scamp5/analognet2/analog_main.h scamp5/analognet2/analog_main.cpp scamp5_extended/scamp5_e.cpp scamp5_extended/scamp5_e.h scamp5_multiplexed/scamp5m.cpp scamp5_multiplexed/scamp5m.h include/simulator/alu/alu.h src/simulator/alu/alu.cpp include/simulator/adc/adc.h src/simulator/adc/adc.cpp include/simulator/metrics/packer.h src/simulator/metrics/packer.cpp include/simulator/metrics/pack_node.h src/simulator/metrics/pack_node.cpp scamp5_multiplexed/scamp5rmalt.cpp scamp5_multiplexed/scamp5rmalt.h scamp5_multiplexed/vj_classifier.cpp scamp5_multiplexed/vj_classifier.h scamp5_multiplexed/image.h)
add_executable(${SIM_LIB} main.cpp src/simulator/registers/analogue_register.cpp include/simulator/registers/analogue_register.h src/simulator/registers/digital_register.cpp include/simulator/registers/digital_register.h src/simulator/buses/analogue_bus.cpp include/simulator/buses/analogue_bus.h src/simulator/buses/digital_bus.cpp include/simulator/buses/digital_bus.h src/simulator/base/pixel.cpp include/simulator/base/pixel.h src/simulator/base/architecture.cpp include/simulator/base/architecture.h src/simulator/pe/processing_element.cpp include/simulator/pe/processing_element.h src/simulator/units/comparator.cpp include/simulator/units/comparator.h src/simulator/units/squarer.cpp include/simulator/units/squarer.h src/simulator/registers/register.cpp include/simulator/registers/register.h src/simulator/base/component.cpp include/simulator/base/component.h src/simulator/memory/dram/dram3t_cell.cpp include/simulator/memory/dram3t_cell.h src/simulator/memory/sram/sram6t_cell.cpp include/simulator/memory/sram6t_cell.h src/simulator/memory/memory.cpp include/simulator/memory/memory.h src/simulator/memory/si/si_cell.cpp include/simulator/memory/si_cell.h src/simulator/util/utility.cpp include/simulator/util/utility.h src/simulator/metrics/cycle_counter.cpp include/simulator/metrics/cycle_counter.h src/simulator/metrics/json_writer.cpp include/simulator/metrics/json_writer.h include/simulator/ui/async_file_streamer.h include/simulator/ui/async_file_reader.h src/simulator/ui/ui.cpp include/simulator/ui/ui.h src/simulator/ui/file_watcher.cpp include/simulator/ui/file_watcher.h include/simulator/ui/base64_encoder.h src/simulator/ui/src/base64_encoder.cpp include/simulator/input/input_source.h src/simulator/input/live_input.cpp include/simulator/input/live_input.h src/simulator/input/image_input.cpp include/simulator/input/image_input.h src/simulator/input/video_input.cpp include/simulator/input/video_input.h include/simulator/base/plane_params.h src/simulator/base/plane_params.cpp include/simulator/adders/cla.h src/simulator/adders/cla.cpp include/simulator/base/config.h src/simulator/base/config.cpp include/simulator/metrics/stats_outputter.h src/simulator/memory/dram/dram_array.cpp include/simulator/memory/dram_array.h include/simulator/external/parser.h src/simulator/external/parser.cpp scamp5/scamp5.h scamp5/scamp5.cpp scamp5/analognet2/conv_instructions.h scamp5/analognet2/fc_weights.h scamp5/analognet2/analog_main.h scamp5/analognet2/analog_main.cpp scamp5_extended/scamp5_e.cpp scamp5_extended/scamp5_e.h scamp5_multiplexed/scamp5m.cpp scamp5_multiplexed/scamp5m.h include/simulator/alu/alu.h src/simulator/alu/alu.cpp include/simulator/adc/adc.h src/simulator/adc/adc.cpp include/simulator/metrics/packer.h src/simulator/metrics/packer.cpp include/simulator/metrics/pack_node.h src/simulator/metrics/pack_node.cpp scamp5_multiplexed/scamp5rmalt.cpp scamp5_multiplexed/scamp5rmalt.h scamp5_multiplexed/vj_classifier.cpp scamp5_multiplexed/vj_classifier.h scamp5_multiplexed/image.h include/simulator/base/opencv_wrappers.h ./src/simulator/base/opencv_wrappers.cpp)

if (WIN32)
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Tracking statistics is expensive and will drastically slow down execution.
| ------------- | ------------- | ------------- |
| USE_RUNTIME_CHECKS | Checks arguments at runtime and emits warnings. | OFF |
| TRACK_STATISTICS | Tracks statistics such as register reads and energy use| OFF |
| USE_CUDA | Uses CUDA for all processing. Obviously a CUDA enabled GPU must be present. Turn TRACK_STATISTICS off because currently there are issues with tracking and CUDA at the same time| OFF |

# Build - (release|debug)
(remmeber to remove the brackets around the choice before running)
Expand All @@ -46,15 +47,16 @@ The main fields are explained here:

| Field name | Required | Default | Description |
| ------------- | ------------- | ------------- | ------------- |
| use_opencl | false | false | Whether to use GPU for processing or CPU. If set and no GPU is available will default to CPU. Uses OpenCL for GPU processing. CUDA can give better performance but this is a compile time option |
| architecture | true | N/A | The name of the architecture that is being simulated. The architecture must be registered and should be a subclass of the `Architecture` class. See `SCAMP5.cpp` for an example architecture |
| frames | false | 1000 | The number of frames to run the program for. A negative number is interpreted as infinite, i.e. run forever|
| frame_time | false | true | Prints the amount of time in ms to process each frame from beginning to end to stdout|
| with_stats | false | false | If this is enabled the statistics of the run will be printed at the end. Must be compiled with statistics support for this to do anything|
| ui_enabled | false | false | Should the web UI server be enabled|
| ui_registers_to_display | true if ui_enabled is set | false | The registers to display on the web UI. Must be defined in the config somewhere and added to the cache (or a property of the architecture)|
| _inherit | false | false | Special field. Sometimes the child component needs to inherit from the parent. This is achieved by use of this special field. The field must be a list of all fields to inherit which have been defined previously. Inheritance is not strictly limited to parents. In fact any property defined previously at any level can be used. This means that if you define the same property in different components only the latest will be preserved.|
| _name | false | false | Special field. Defines the identifier of the component|
| _component | false | false | Specifal field. The component class. Must match exactly so the correct class can be found and constructed|
| _inherit | false | N/A | Special field. Sometimes the child component needs to inherit from the parent. This is achieved by use of this special field. The field must be a list of all fields to inherit which have been defined previously. Inheritance is not strictly limited to parents. In fact any property defined previously at any level can be used. This means that if you define the same property in different components only the latest will be preserved.|
| _name | false | N/A | Special field. Defines the identifier of the component|
| _component | false | N/A | Specifal field. The component class. Must match exactly so the correct class can be found and constructed|


The architecture set in the `architecture` field must be defined as an object. This part is hierarchical. You can add define each component that is necessary in the definition of the architecture.
Expand Down
9 changes: 5 additions & 4 deletions examples/multiplex/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"architecture": "SCAMP5M",
"frames": 25,
"frames": 1,
"with_opencl": true,
"with_stats": true,
"ui_enabled": true,
"output_filename": "",
Expand All @@ -9,7 +10,7 @@
"rows": 256,
"cols": 256,
"row_stride": 1,
"col_stride": 1,
"col_stride": 256,
"origin": "TOP_RIGHT",
"config": {
"clock_rate": 10000000
Expand Down Expand Up @@ -39,8 +40,8 @@
],
"_component": "Dram",
"_name": "dram",
"array_rows": 500,
"array_cols": 32
"array_rows": 256,
"array_cols": 90
},
{
"_inherit": [
Expand Down
3 changes: 3 additions & 0 deletions examples/multiplex/downsample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//get_image(A, D);
downsample(B, A, 0.5);
//display()
1 change: 1 addition & 0 deletions examples/multiplex/integral.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
integral_image()
2 changes: 1 addition & 1 deletion examples/scamp5/box3x3.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// 3x3 box filter
get_image(A, D)
//get_image(A, D)
diva(A, B, C);
diva(A, B, C);
diva(A, B, C);
Expand Down
30 changes: 16 additions & 14 deletions examples/scamp5/config.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"architecture": "SCAMP5",
"frames": 1,
"frame_time": true,
"with_stats": true,
"frames": 10000,
"use_opencl" : false,
"instr_rep" : 1,
"frame_time": true,
"with_stats": false,
"ui_enabled": true,
"ui_registers_to_display" : ["A", "B", "C", "D", "E", "R5", "R6", "R7", "R12"],
"ui_registers_to_display" : ["A", "B", "C", "D", "E", "R5", "R6", "R7", "R12"],
"SCAMP5": {
"rows": 256,
"cols": 256,
Expand All @@ -13,19 +15,19 @@
"origin" : "TOP_RIGHT",
"config": {
"process_node" : 180,
"clock_rate" : 1e7
"clock_rate" : 1e7
},
"components" : [
{
"_inherit" : ["config", "rows", "cols", "row_stride", "col_stride"],
"_component" : "ProcessingElement",
"_name" : "pe",
"analogue_registers" : ["PIX", "IN", "NEWS", "A", "B", "C", "D", "E", "F"],
"digital_registers" : ["FLAG", "SELECT", "RECT", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", {"name" : "R12", "mask" : "R0"}],
"pixel" : {
{
"_inherit" : ["config", "rows", "cols", "row_stride", "col_stride"],
"_component" : "ProcessingElement",
"_name" : "pe",
"analogue_registers" : ["PIX", "IN", "NEWS", "A", "B", "C", "D", "E", "F"],
"digital_registers" : ["FLAG", "SELECT", "RECT", "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", {"name" : "R12", "mask" : "R0"}],
"pixel" : {
"camera_index" : 0,
"input_source" : "LIVE"
}
"input_source" : "LIVE"
}
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion examples/scamp5/gaussian3x3.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
get_image(A, D);
//get_image(A, D);
divq(C, A);
divq(A, C);
divq(C, A);
Expand Down
2 changes: 1 addition & 1 deletion examples/scamp5/gaussian5x5.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
get_image(A, D);
//get_image(A, D);
div(E, C, A);
diva(E, C, B);
diva(E, C, B);
Expand Down
2 changes: 1 addition & 1 deletion examples/scamp5/horizontal_sobel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ movx(B, A, west);
addx(A, B, A, east);
addx(B, B, A, south);
sub2x(A, B, north, north, B);
display();
//display();
11 changes: 11 additions & 0 deletions examples/scamp5/laplacian.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//get_image(A, D);
movx(F, A, north);
neg(B, A);
subx(D, F, south, B);
sub(C, D, B);
add(D, D, C);
subx(E, B, south, F);
addx(A, B, E, west);
mov2x(B, A, east, east);
add(C, C, D, E);
add(A, C, A, B);
2 changes: 1 addition & 1 deletion examples/scamp5/lat.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// local adaptive thresholding.
// works decently with 512x512 resolution images of say book pages
get_image(A, D)
//get_image(A, D)
div(B, C, A);
diva(B, C, D);
diva(B, C, D);
Expand Down
18 changes: 18 additions & 0 deletions examples/scamp5/mean3x3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//get_image(A, D);
div(C, D, A);
diva(C, D, E);
diva(C, D, E);
diva(C, D, E);
diva(C, D, E);
diva(C, D, E);
movx(D, C, south);
movx(E, C, north);
add(A, D, C, E);
add(B, D, C, E);
add(C, D, C, E);
add(B, A, B, C);
add(A, B, A);
add(B, A, B);
movx(A, B, east);
movx(C, B, west);
add(B, B, C, A);
7 changes: 3 additions & 4 deletions examples/scamp5/motion.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
get_image(C,D);
scamp5_in(E, 15)
//get_image(C,D);
scamp5_in(E, 15);
sub(D,C,F); // D = C - F
mov(F,C); // F = C
abs(B,D); // B = |D|
sub(A,B,E); // A = B - E
where(A); // where A > 0
MOV(R5, FLAG);
all();
//motion()
display()
//display()
2 changes: 1 addition & 1 deletion examples/scamp5/multiple_sobel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ addx(C, C, A, north);
addx(B, B, D, east);
sub2x(A, B, west, west, B);
sub2x(B, C, south, south, C);
display()
//display()
4 changes: 2 additions & 2 deletions examples/scamp5/vertical_sobel.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
get_image(A, D)
//get_image(A, D)
movx(B, A, south);
addx(A, B, A, north);
addx(B, B, A, east);
sub2x(A, B, west, west, B);
display()
//display()
2 changes: 1 addition & 1 deletion include/simulator/adders/cla.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CarryLookAheadAdder : public Component {
double calc_width() override;
double calc_height() override;
#endif
cv::Mat scratch;
cv::UMat scratch;

public:
CarryLookAheadAdder() = default;
Expand Down
21 changes: 16 additions & 5 deletions include/simulator/base/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <nlohmann/json.hpp>
#include <opencv2/core.hpp>
#include <opencv2/core/cuda.hpp>
#include <rttr/registration>
#include <memory>

Expand All @@ -22,15 +23,20 @@ class Component : public StatsOutputter {
std::shared_ptr<PackNode> fit;

protected:
int process_node_ = -1; // process node in nm that the other metrics are defined in terms of. for example
int process_node_ = 180; // process node in nm that the other metrics are defined in terms of.
int rows_; // rows of the whole plane
int cols_; // cols of the whole plane
int row_stride_ = 1;
int col_stride_ = 1;
std::shared_ptr<Config> config_;
cv::Mat internal_mask; // Used to keep track of components in array when stride is not 1, i.e. spaces between components
#ifdef USE_CUDA
cv::cuda::GpuMat internal_mask; // Used to keep track of components in array when stride is not 1, i.e. spaces between components
#else
cv::UMat internal_mask; // Used to keep track of components in array when stride is not 1, i.e. spaces between components
#endif

public:
void init();
void calc_internal_mask();

/*Setters*/
Expand All @@ -50,12 +56,17 @@ class Component : public StatsOutputter {
double dynamic_power_; // in Watts
double width_; // in Micrometres
double height_; // in Mircometres
cv::Mat array_transistor_count_;
cv::Mat array_static_energy_;
cv::Mat array_dynamic_energy_;
cv::UMat array_static_energy_;
cv::UMat array_dynamic_energy_; // No GPUMat for these two as float ops are not always supported on GPUs but int ops usually are
#ifdef USE_CUDA
cv::cuda::GpuMat array_transistor_count_;
#else
cv::UMat array_transistor_count_;
#endif
public:
/* Update component with how much time has passed for operation. Used for updating static power. */
virtual void update_static(double time) = 0;

/* Returns the total amount of static energy use */
virtual cv::Mat get_static_energy_array();
/* Returns the total amount of dynamic energy use */
Expand Down
21 changes: 21 additions & 0 deletions include/simulator/base/opencv_wrappers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Created by jm1417 on 29/05/2021.
//

#ifndef SIMULATOR_OPENCV_WRAPPERS_H
#define SIMULATOR_OPENCV_WRAPPERS_H

#include <opencv2/core.hpp>
#include <opencv2/core/cuda.hpp>

/*Wrappers around common OpenCV functionality which makes GPU switching easy */

namespace ocv_wrappers::arith {
void add(cv::OutputArray dst, cv::InputArray src1, cv::InputArray src2);
void add(cv::OutputArray dst, cv::InputArray src1, cv::InputArray src2, cv::InputArray mask);

}



#endif //SIMULATOR_OPENCV_WRAPPERS_H
6 changes: 5 additions & 1 deletion include/simulator/base/pixel.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ class Pixel : public Component {

void reset();
void read(Register& reg);
cv::Mat read();
#ifdef USE_CUDA
cv::cuda::GpuMat& read();
#else
cv::UMat& read();
#endif
double last_frame_time();
#ifdef TRACK_STATISTICS
int calc_transistor_count() override;
Expand Down
6 changes: 5 additions & 1 deletion include/simulator/buses/analogue_bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

class AnalogueBus {
private:
cv::Mat scratch;
#ifdef USE_CUDA
cv::cuda::GpuMat scratch;
#else
cv::UMat scratch;
#endif

public:
// Analogue Register Transfer
Expand Down
4 changes: 4 additions & 0 deletions include/simulator/external/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class Parser {
Parser();
std::vector<rttr::enumeration> enums_;
ParserCache cache;
int repeat_ = 1; // Number of times to repeat each instruction. Useful for performance testing


public:
static Parser& get_instance(){
Expand All @@ -37,6 +39,8 @@ class Parser {
void set_property(const rttr::type& arch_type, const rttr::variant& arch, const std::string& name, rttr::variant value);
rttr::variant create_instance(const std::string& arch_name, json arch_props);
void parse_config(std::ifstream& config, std::ifstream& program);

void setup_processing(json& j);
};

#endif //SIMULATOR_PARSER_H
6 changes: 5 additions & 1 deletion include/simulator/input/image_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ class ImageInput : public InputSource {
public:
ImageInput(int rows, int cols, const std::string& path);
void read(Register& reg) override;
cv::Mat read() override;
#ifdef USE_CUDA
cv::cuda::GpuMat& read() override;
#else
cv::UMat& read() override;
#endif
void reset() override;
double last_frame_time() override;
};
Expand Down
Loading