diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed51497 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Cmake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app +Tests/GCD +Tests/AutoTest diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0b76319 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory("Lib") \ No newline at end of file diff --git a/Lib/CMakeLists.txt b/Lib/CMakeLists.txt new file mode 100644 index 0000000..17ebeb6 --- /dev/null +++ b/Lib/CMakeLists.txt @@ -0,0 +1,103 @@ +message(STATUS "Creating Makefile for QPULib") + +#QPULib uses assert statements that throw errors when compiling with g++ on platforms other than the Pi +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_definitions(-fpermissive) +endif() + +#file(GLOB_RECURSE QPULIB_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") +#message(STATUS "QPULib library source files: ${QPULIB_SOURCES}") +#file(GLOB_RECURSE QPULIB_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h" "*.hpp") + +include_directories("${CMAKE_CURRENT_SOURCE_DIR}") + + +# Compile Invoke, Mailbox, VideoCore if not emulating +# Check if this is a Pi +# Compile differently for the Raspberry Pi +find_path(HAS_BCMHOST bcm_host.h PATHS /opt/vc/include/) +if (HAS_BCMHOST) #This is a Pi + add_definitions(-DQPU_MODE) + add_definitions(-fpermissive) + add_definitions(-std=c++0x) + SET(QPULIB_SOURCES + ${QPULIB_SOURCES} + VideoCore/Invoke.cpp + VideoCore/Mailbox.cpp + VideoCore/VideoCore.cpp + VideoCore/Invoke.h + VideoCore/Mailbox.h + VideoCore/VideoCore.h + ) + +else() #Not compiling on the Pi + add_definitions(-DEMULATION_MODE) + +endif() + +SET(QPULIB_SOURCES + ${QPULIB_SOURCES} + #Source files + Kernel.cpp + Source/Float.cpp + Source/Gen.cpp + Source/Int.cpp + Source/Interpreter.cpp + Source/Pretty.cpp + Source/Stmt.cpp + Source/Syntax.cpp + Source/Translate.cpp + Target/CFG.cpp + Target/Emulator.cpp + Target/Encode.cpp + Target/Liveness.cpp + Target/LiveRangeSplit.cpp + Target/LoadStore.cpp + Target/Pretty.cpp + Target/ReachingDefs.cpp + Target/RegAlloc.cpp + Target/RemoveLabels.cpp + Target/Satisfy.cpp + Target/SmallLiteral.cpp + Target/Subst.cpp + Target/Syntax.cpp + #Header files + Common/Heap.h + Common/Seq.h + Common/Stack.h + Kernel.h + Params.h + QPULib.h + Source/Cond.h + Source/Float.h + Source/Gen.h + Source/Int.h + Source/Interpreter.h + Source/Pretty.h + Source/Ptr.h + Source/Stmt.h + Source/StmtExtra.h + Source/Syntax.h + Source/Translate.h + Target/CFG.h + Target/Emulator.h + Target/Encode.h + Target/Liveness.h + Target/LiveRangeSplit.h + Target/LoadStore.h + Target/Pretty.h + Target/ReachingDefs.h + Target/RegAlloc.h + Target/RemoveLabels.h + Target/Satisfy.h + Target/SmallLiteral.h + Target/Subst.h + Target/Syntax.h + VideoCore/SharedArray.h +) + + +add_library(QPULib +STATIC +${QPULIB_SOURCES} +) diff --git a/Lib/Kernel.h b/Lib/Kernel.h index 72bf96b..f16e171 100644 --- a/Lib/Kernel.h +++ b/Lib/Kernel.h @@ -5,8 +5,10 @@ #include "Target/Emulator.h" #include "Target/Encode.h" #include "VideoCore/SharedArray.h" +#ifdef QPU_MODE #include "VideoCore/Invoke.h" #include "VideoCore/VideoCore.h" +#endif // ============================================================================ // Modes of operation diff --git a/Lib/Source/Stmt.cpp b/Lib/Source/Stmt.cpp index 16715c4..04390dd 100644 --- a/Lib/Source/Stmt.cpp +++ b/Lib/Source/Stmt.cpp @@ -217,9 +217,9 @@ void kernelFinish() Int n = numQPUs()-1; For (Int i = 0, i < n, i++) semaDec(15); - End + EndBlock hostIRQ(); Else semaInc(15); - End + EndBlock } diff --git a/Lib/Source/Stmt.h b/Lib/Source/Stmt.h index 496ac17..9cfde1b 100644 --- a/Lib/Source/Stmt.h +++ b/Lib/Source/Stmt.h @@ -12,7 +12,7 @@ #define If(c) If_(c); { #define Else } Else_(); { -#define End } End_(); +#define EndBlock } End_(); #define While(c) While_(c); { #define Where(b) Where_(b); { #define For(init, cond, inc) \ diff --git a/Lib/VideoCore/SharedArray.h b/Lib/VideoCore/SharedArray.h index b1ee0eb..824d835 100644 --- a/Lib/VideoCore/SharedArray.h +++ b/Lib/VideoCore/SharedArray.h @@ -4,8 +4,11 @@ #include #include #include -#include "VideoCore/Mailbox.h" -#include "VideoCore/VideoCore.h" + +#ifdef QPU_MODE + #include "VideoCore/Mailbox.h" + #include "VideoCore/VideoCore.h" +#endif #ifdef EMULATION_MODE diff --git a/README.md b/README.md index 8f06b75..4c9fe2e 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ Pi](https://www.raspberrypi.org/)'s *Quad Processing Units* (QPUs). It is implemented as a C++ library that runs on the Pi's ARM CPU, generating and offloading programs to the QPUs at runtime. This page introduces and documents QPULib. For build instructions, see the -[Getting Started Guide](Doc/GettingStarted.md). +[Getting Started Guide](Doc/GettingStarted.md) and the +[CMake build instructions](README_CMake.md). ## Contents @@ -129,11 +130,11 @@ void gcd(Ptr p, Ptr q, Ptr r) While (any(a != b)) Where (a > b) a = a-b; - End + EndBlock Where (a < b) b = b-a; - End - End + EndBlock + EndBlock *r = a; } ``` @@ -155,7 +156,7 @@ Even this simple example introduces a number of concepts: * the condition `any(a != b)` is true when *any* of the booleans in the vector `a != b` are true; - * the statement `Where (a > b) a = a-b; End` is a conditional assigment: + * the statement `Where (a > b) a = a-b; EndBlock` is a conditional assigment: only elements in vector `a` for which `a > b` holds will be modified. @@ -263,12 +264,12 @@ void gcd(Ptr p, Ptr q, Ptr r) for (int i = 0; i < 32; i++) { Where (a > b) a = a-b; - End + EndBlock Where (a < b) b = b-a; - End + EndBlock } - End + EndBlock *r = a; } ``` @@ -328,7 +329,7 @@ void rot3D(Int n, Float cosTheta, Float sinTheta, Ptr x, Ptr y) Float yOld = y[i]; x[i] = xOld * cosTheta - yOld * sinTheta; y[i] = yOld * cosTheta + xOld * sinTheta; - End + EndBlock } ``` @@ -399,7 +400,7 @@ void rot3D(Int n, Float cosTheta, Float sinTheta, Ptr x, Ptr y) store(xOld * cosTheta - yOld * sinTheta, p); store(yOld * cosTheta + xOld * sinTheta, q); p = p+16; q = q+16; - End + EndBlock // Discard pre-fetched vectors from final iteration receive(xOld); receive(yOld); @@ -443,7 +444,7 @@ void rot3D(Int n, Float cosTheta, Float sinTheta, Ptr x, Ptr y) store(xOld * cosTheta - yOld * sinTheta, p); store(yOld * cosTheta + xOld * sinTheta, q); p = p+inc; q = q+inc; - End + EndBlock // Discard pre-fetched vectors from final iteration receive(xOld); receive(yOld); @@ -587,7 +588,7 @@ class Cursor { Float nextRot = rotate(next, 15); Where (index() == 15) result = nextRot; - End + EndBlock } // Shift the current vector right one element @@ -596,7 +597,7 @@ class Cursor { Float prevRot = rotate(prev, 1); Where (index() == 0) result = prevRot; - End + EndBlock } }; ``` @@ -646,14 +647,14 @@ void step(Ptr grid, Ptr gridOut, Int pitch, Int width, Int height) store(row[1].current - K * (row[1].current - sum * 0.125), p); p = p + 16; - End + EndBlock // Cursors are finished for this row for (int i = 0; i < 3; i++) row[i].finish(); // Move to the next input rows grid = grid + pitch*numQPUs(); - End + EndBlock } ``` diff --git a/README_CMake.md b/README_CMake.md new file mode 100644 index 0000000..0464136 --- /dev/null +++ b/README_CMake.md @@ -0,0 +1,73 @@ +# Bulding with CMake +## Introduction + +This document explains how to make a project with QPULib and CMake. +An example CMake project has been set up +[here](https://github.com/m516/PiGPGPU) +as reference and to be used as a template for new projects. + +The general file structure for a C++ project with QPULib is like so: +``` +lib/ + QPULib/ + QPULib source files + +src/ + + CMakeLists.txt +CMakeLists.txt +``` + +If prepared properly, your project can be easily built on Windows, +Mac OS, and Linux platforms, even though QPULib targets Raspberry Pi +hardware. The example project has been tested with Windows 10, +Raspbian Buster on a Pi 0W, and Ubuntu with minimal configuration on +all platforms. + +## Writing CMake Scripts +CMake scripts are a pain in the butt to set up, but they make the build +process easy. CMake reads text files with the name `CMakeLists.txt` +and generates Makefiles. The Makefiles are interpreted by Make to +build your project with the C++ compiler on your OS. + +The `CMakeLists.txt` file in the root directory should be used to +set up the project, store the list of libraries, and start the build +processes for all your subprojects. +```CMake +# CMakeList.txt : Top-level CMake project file, do global configuration +# and include sub-projects here. +# +cmake_minimum_required (VERSION 3.8) + +project (PiGPGPU) + +# Include libraries +add_subdirectory("lib") + + +#Compile differently for the Raspberry Pi +find_path(HAS_BCMHOST bcm_host.h PATHS /opt/vc/include/) +if (HAS_BCMHOST) #This is a Pi + message(STATUS "This is a Pi") + message(STATUS "Targeting VideoCore IV GPU") + #Set precompiler flags + add_definitions(-DQPU_MODE) + +else() #Not compiling on the Pi + message(STATUS "This is not a Pi") + message(STATUS "Emulating Pi's GPU") + #Add precompiler definitions + add_definitions(-DEMULATION_MODE) +endif() + +#Include QPULib +add_subdirectory("lib/QPULib") +include_directories("${PROJECT_SOURCE_DIR}/lib/QPULib/Lib") + +add_subdirectory("src") +``` + +## Conclusion +If you have any suggestions or issues, I'd love to hear them and help! +The best way to contact me is the issues tab of the Github repository. +Good luck and happy hacking! diff --git a/Tests/Makefile b/Tests/Makefile index a23b0c8..b7b5323 100644 --- a/Tests/Makefile +++ b/Tests/Makefile @@ -3,7 +3,7 @@ ROOT = ../Lib # Compiler and default flags CXX = g++ -CXX_FLAGS = -Wconversion -std=c++0x -I $(ROOT) +CXX_FLAGS = -fpermissive -Wconversion -std=c++0x -I $(ROOT) # Object directory OBJ_DIR = obj