Anda di halaman 1dari 26

Novel Approaches to Programming Heterogeneous Computational Systems

Alexander Thomas, MEng

Abstract
With constant acceleration in the development of innovative electronic systems, there is a
comparable growth in their complexity. Systems comprising of multiple interconnected computational devices possessing diverse functionality have become commonplace, and are the foundations
of the increasingly popular system-on-a-chip paradigm. Whilst boasting increased performance
and driving down power consumption, these heterogeneous systems are significantly difficult to
implement and maintain in practice. Varying device architectures, dependence on numerous
integrated development environments, limited flexibility of intellectual property, the necessity
for platform-specific expertise and compensation for device-specific idiosyncrasies all conspire
against the development process. Meanwhile, designers must race against the clock of impending
hardware obsolescence. This report will provide reasoning for methods by which heterogeneous
system prototyping may be eased via the implementation of a flexible software environment that
aims to encapsulate and suppress the difficulties of contemporary heterogeneous design.

Disclaimer: This paper contains original intellectual property. Although Ive grown quite accustomed to unfounded accusations of patent infringement, I insist that my permission is sought
prior to exposing these works to representatives of industrial bodies external to the university.
Acknowledgements: I must express my sincerest gratitude to the university for this outstanding
opportunity, in particular to my supervisor Dr. Roelof van Silfhout, whom without his patience
with my independent experimentation none of this would be possible.

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Contents
1 Introduction

2 Aims and Objectives

3 Field Review

4 Design
4.1 Spatial Programming . . . . . . . . . . . . . . .
4.2 The Punch Programming Language . . . . . . .
4.3 Heterogeneity and the Principia Mathematica .
4.4 Superseding, or Having our Cake and Eating It

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

7
7
8
12
15

5 Punch Programming Language Specifcation (2016)

21

6 Further Work

23

7 Conclusion

23

8 Project Management

24

The way to solve the conflict between human values and technological needs is not to run away from technology. Thats impossible. The way to resolve the conflict is to break down the barrier of dualistic thought that
prevents a real understanding of what technology is - not an exploitation of nature, but a fusion of nature
and the human spirit into a new kind of creation that transcends both.
- Robert M. Pirsig, Zen and the Art of Motorcycle Maintenance

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Introduction

The aim of this report is to provide reasoning for the development of a platform-independent programming paradigm which views runtime hardware, descriptions of computation and interactions with peripheral
devices with an unparalleled level of agnosticism. Its my perogative to do this whilst working through an
objective assessment of the common conventions in graphical programming and their subtle disharmony with
the proliferation of powerful touch screen enabled devices. Users are becoming increasingly reliant upon the
tangibility of an application, and I will convey how we may take advantage of this tangibility; this instinctive
physical interaction with written software, as a potential conduit for conveying fundamental natures of an
algorithmic procedure. I propose that these seemingly playful intuitions may be utilised to form the basis
of a spatial programming language; one thats intutitive, simple and modern.
I demonstrate that by making an analysis of the alignment between graphical entities across the vertical
axis in a planar language, were capable of supposing sequences of data transit and assosciated memory
operations in a highly abstract and visually consistent manner. Using a similar supposition, the order of
execution between these entities may be defined by their respective locations along the horizontal plane.
Such an approach results in an executable graph of computation that may be likened to punched card
technology once used to automate hardware operations. Though historically the punched card described
low level digital manipulation, it is possible to demonstrate how a dynamic software equivalent may be
used to convey higher-level programmatic concepts such as object-oriented data types, control flow and data
dependencies.
Physical interactions with modern touch screens are broad; your fingertips stimulate numerous capacitative sensors whose values swiftly ripple through a sophisticated analytic process that vies to reconcile
your analogue touch to a discrete pixel-perfect position. A similar analogy can be used in terms of a spatial
language; if alignment is our stepping-stone to expression, the imprecise arrangements of a user absolutely
has to be coerced in a way which is conducive to dataflow. This coercion is achieved through the application of a deterministic distribution engine which dynamically responds to the programmer throughout the
development cycle, resulting in a graphical language whose syntax is not just immediately parsed, but also
consistently clean.
In contrast to my earlier works, this text will assess the implementation of the language from a topdown narrative. It is my ambition that this approach instills three overriding themes in the reader. Firstly,
you will learn from first principles how to implement a range of algorithmic procedures using the adopted
conventions of a spatial programming language. In effect, this document should serve you as both your
introduction to spatial programming and your development guide. Secondly, you will build a comprehensive
understanding of just how these procedures may in turn be automatically implemented on the physical gate
level, irrespective of the overarching complexity, in an effort to achieve the elusive common ground between
heterogeneous systems. Finally, I will reason about how this language may be comprised of interchangeable
server-persisted submodules in an effort to tune runtime performance, promote advantageous utilisation of
a hardware platform, integrate with existing design automation tools and present itself as a framework for
novel applications.
We truly stand on the shoulders of giants. The ideas I present in this paper are the culmination of years
worth of hypothetical questions, naive what if?s, that Ive accumulated over the course of my long love affair
with the stimulating world of graphical programming.
Without further ado, I humbly present to you the Punch Programming Language.

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Aims and Objectives

In this report, were going to build up some understanding of the contemporary approaches to graphical
programming, the software and prototyping elements of heterogeneous system design and bespoke representations of a novel programming language known as a spatial language. Well discuss the nature, usage and
rules of a spatial programming language, its potential application to systems level programming, and reason
about its wide applicability to diverse modes of interaction. An analysis of the supporting frameworks for a
spatial language, from distribution to compilation and simulation to characterisation, will be presented. We
will engage in a discussion of the potential benefits to platform independent algorithmic representations in
an effort to achieve broad hardware and runtime diversity, and just how this approach may be encompassed
by a spatial development tool.
By the end of this report, you will be capable of the following:
Discussing the most widely used conventions in graphical programming
Comparing the relative benefits and drawbacks between textual and visual programming
Acknowleding the formal conventions of spatial programming
Interpreting procedural and concurrent algorithms written in the Punch Programming Language
Reasoning about an axiomatic approach to software representation
Defining the attributes of runtime systems necessary for abstraction in platform independent programs
Explaining how software designs may be optimised through cataloguing preferred implementation types

Field Review

All human consciousness, regardless of culture or prejudice or intelligence, has a priori ideas of efficiency,
instinctive desires for performance, is tormented by the irreconcilable and seeks to answer vast immortal
questions through incorruptable logic. If these ingrained traits dont characterise the state of mind adopted
by the hardened programmer, Im at a loss to explain what does. I believe that its this state of mind that
developers yearn to accommodate within their own language frameworks, in an effort to increase the cohesion
between a programmers mental processes and a computers formulaic description until their differences grow
negligible and the two finally become synonymous.
In our eternal strive for perfection, the tools at our disposal grow ever more capable, more diverse in
their application, more performant, and most importantly of all more in tune with the contemporary state of
human ideology. Consequently, the nature of human interaction with technological platforms is ever-changing
and the field of computer programming should consider itself no different. Even from the beginning of this
stunning digital age, various imaginative approaches to the technical representations of computer code have
been developed as a means emancipate expression and inspire an increasingly technologically-aware public
of their innate capabilities as a programmer; the invisible undercurrent of their everyday thought processes.
However, we must analyse a subtle disparity in this great field that may be contextualised by the current
predominance of mobile devices. One does not have to look hard to find an avid reader engrossed in a digitized
book on the public transport system, or the commutor who is capable of mulling over a complex spreadsheet
with the casual swipe of a thumb as if he werent racing along the train tracks at over a hundred miles an
hour. Of course, this is the dawn of the Internet of Things (IoT), and such sights are commonplace; but
Im willing to make a bet that you havent ever seen anybody programming with that much ease, and thats
not through lack of trying. Theres more talent, online communities, vocations and government funding in
support of computer programming than there ever has been in history[1], and yet there has been no such
Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

uptake on handheld devices, arguably a cornerstone of modern Western civilisation, in the quite same way.
Its my plan to dedicate some time in this report to understand just why this is.
First, lets take a look at text-based languages. Broadly, these are comprised of a series of lexical flags
which are in most cases human readable. Usually when we refer to such languages as being high level, this
is with regards to the amount of complexity that may be hidden away within as succinct a statement in
that language as possible. These statements, when combined together into text files commonly referred to as
source files, may then be interpreted and compiled by a computer. This is what makes these programs into
something that runs. To reach this stage, however, the compilation computer necessitates strict rules and
understanding of just how source files may be processed. Similarly, development of the executable file itself
necessitates some knowledge of the target runtime platform when concerning how much memory it may use,
how long intensive routines may take to execute, what features are available, or what devices it has at its
disposal.
Textual languages share the wide majority of popularity in the field of computer programming (of the
top ten, none are graphical[2]) and should therefore be given the most focus during our analysis of modern
programming on mobile platforms. Since Ive alluded to the mass ubiquity of mobile devices and my goals
of proposing these as an advantageous development platform, its important for us to make a qualitative and
quantative assessment of the takeup of the existing take up in the device market. On the surface, text-based
software development seems a natural fit; after all, people type on them every single day. So why isnt it?
In text-based programming, the channel of communication between
the programmer and the compiler is the keyboard; after all, this is the
only means by which the algorithm can be created and described. In
this respect, its important to look at the plausability of touchscreen keyboards for realistic software development. Source files are often verbose,
especially in enterprise-level designs, which equates glumly to an inordinate amount of typing. Weve seen the speed by which those most
attached to their mobile phones are able to fire off a text message; but
can this translate to programming? In practice, the rapid taps of a texting digit are analysed by sophisticated learning algorithms which take
a users imprecise press on a software keyboard and maps it to a virtual key that was most likely meant, meaning that text prediction initiatives such as SwiftKey[3] have grown extremely influential in the field, Figure 1 A child raised using
and widely adopted; not to mention profitable[4]. These are generally tablet devices fruitlessly swipes
dictionary-based, and use the constructs of formal languages in their pre- at a magazine.[5]
diction schemes. When taken directly, such analysis frameworks would
be woefully unsuitable for use in computer programming given their totally incomparble approaches to interpreting source text, however this does not limit their applicability;
surely the same schemes may be implemented for source code given its reduced complexity (in terms of
the narrow lexical range expected by programming languages when compared to grammatical diction). But,
there are some problems. A programmers keyboard would require knowledge of the target language
and application-dependent project structure in order to provide meaningful auto-completion reminiscent
of integrated development environments, in some way that would not obscure the alphanumeric interface.
Additionally, conventional programming languages regularly rely upon special characters which arent immediately available in the default keyboard pane and are usually accessed via a secondary interface, which
necessitates multiple presses or selection delays in order to print a single character. This burden also applies
to capitalisation, another mainstay of virtuous programming. Software keyboards also commonly overlap
at least half of the touch screen; this hinders the ability of a programmer to visualise a lengthy procedure
in its full structure and therefore increases the difficulty of development. Most importantly of all, textual
representation of verbose code does not scale well; we need only remind ourselves of the importance of being
able to resize the contents of a webpage when browsing on a handheld device. This reasoning leads me

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

to conclude that many of the common conventions in efficient text-typing on mobile devices may actually
conspire against text programming!
Theres no doubt in my mind that every one of these proposed barriers to mobile platform development
could be imaginatively eradicated in an effort to influence adoption by programmers worldwide; but as
scientists, mathematicians, engineers and artists, we commit ourselves to seek out the most effective solutions
as these are the most robust, and there is a more robust solution; graphical programming.
Alternatively to describing software using written text, graphical programming enables software developers to write functional programs through the creation of a pictorial diagram. Function calls and data
propagation are represented using symbolic representations which allow programmers to sidestep manually
typing them. In contrast to text descriptions of code, graphical diagrams are intrinsically parsed as they
depend upon fixed graphical elements instead of error-prone developer-dependent typed code. Thanks to
their unique visual designs, graphical languages support novel representations of control flow which improve
readability of code; for example, sequential and concurrent regions are visually distinct, in stark constrast to
the often deeply misleading layout of consecutive statements in a textual source file.
Unlike text-based programming, the versatility of a graphical source file is greatly reduced due to the
vendor-dependent nature of graphical representations. Often a specific environment must be sought out in
order to modify a graphical source file, contrary to text code which may be manipulated in any text editor at
all. These binary representations diminish the applicability of version control software that aids developers
to manage and integrate code modifications in lenthy designs.
In graphical languages, executable syntax is commonly represented using icons which may be repositioned
across the wide expanse of an unbounded diagram. Supporting development environments therefore usually
rely on drag-and-drop as the core mechanism of writing code, which has historically resulted in the computer
mouse or trackpad being selected as the weapon of choice for a graphical programmer. It must therefore
be emphasised at this stage that the applicability of multi-touch screens for graphical programming is very
clear, as touch screen interfaces not only very closely match but also improve upon the tangible interaction
capabilities of an ordinary mouse. Its vital to note at this stage that we must not downplay the increasing
importance of tangibility in applications driven by a user interface. Younger generations are being raised
in a modern world filled with tablet devices that are both their toy and their tutor (Figure 1), and these
all embrace gesture-driven interaction. In light of these factors, were lured to assess whether graphical
programming has fared any better than textual programming on mobile devices.
A sweeping analysis of the mobile applications market suggests that there is indeed a pattern emerging.
The applicability of modern mobile devices to graphical programming has culminated in the production
of a range of different prototyping platforms, though the majority of which are comprised of rudimentary
educational tools or limited high-level programming libraries for commercial products. These packages are
suitable for their respective target applications, but are isolated; they lack the broadness of general-purpose
programming languages that were really reaching out for. That is, of course, except for MITs Scratch and
Googles Blockly.
Scratch [6] is a platform that enables developers to create games, animations and interactive stories using
a programming environment which renders lexical programming constructs as equivalent graphical blocks
(Figure 2). In this regard, Scratch remains tied to the conventions in textual programming without burdening the developer with most of the typing. Going forward, Googles Blockly built upon the approach
taken by the Scratch multimedia platform to provide support for Scratch code to be exported to a number of different scripting languages such as JavaScript, Python and PHP[7]. Both of these environments
have received a very positive reception from their dedicated online communities and their open application
programming interfaces have been repackaged widely. Most impressively, Blockly has achieved the broad
applicability of general-purpose programming through scripting-language agnosticism, whilst simultaneously
taking advantage of mobile platforms.
Reminding ourselves of the evolutionary nature of technology, I will venture to make some spirited
discussion of the platforms shortfalls. Firstly, I must confess to playing devils advocate in suggesting

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

that the Scratch approach doesnt truly correspond to the conventions of graphical programming. I must
emphasise this is not a drawback by any means, and I cannot reason of a more apt approach to uniting
conventions in visual programming with textual code; but it is undeniably a textual language and therefore
suffers from aforementioned issues in a written representation. As a loosely-typed language, it also poses
a significant overhead when targeting low-level digital platforms as it would require a formidable runtime
engine to serve as a silent conductor for managing salient unknown variable assignments at runtime. As
Blockly relies upon its own syntax, it is necessary for developers to study textual language constructs
irrespective of the fact they are confined to the use of fixed blocks, unlike graphical programming which
uses intuitive iconic representations. Further to this, though Blockly highlights control flow to the user using
shapely coloured nesting, the lifetime and usage of allocated variables is not immediately apparent. As
the environment is forced to maintain a very rigid structure of code, there is a limit to the ease by which
sequences of instructions may be re-arranged at development time; and as concurrency is limited to code
definitions on separate parallel stacks, nested regions of concurrency within procedural routines and their
relative scopes to shared variables are as of yet undefined [8]. This hinders its applicability to the increasing
utilisation of highly parallelised devices.
This analysis leads me to conclude that there is a potential audience
for software development on mobile platforms, though at the time of writing, there are no solutions for professional-level mobile development for
broad applications in the scientific and engineering domain. What we
have discussed, however, are many of the proven foundations of one.

4
4.1

Design
Spatial Programming

Figure 2 A maze solving algoContemporary graphical programming languages rely upon the common
rithm written in Blockly; escape
convention that dataflow between successive function calls may be brought
any maze by following the left
about by manually wiring a data connection between a source of data
hand side.
and a compatible sinking terminal, which implicitly defines the mode of
execution. In synchronous dataflow languages such as LabVIEW [9] or
Simulink[10], a wire forces procedural execution by limiting the execution
of a function until it has collected all of its data dependencies. Conversely,
within flow-based languages such as NoFlo[11] or Pure Data[12], wires
represent a message-based line of communication which asynchronously executes functions using eventdriven logic. Though fundamentally both approaches adopt a mutually consistent and expressive graphical
specification of data transmission, the schools of thought in interpreting execution of the languages are
utterly irreconcilable with one-another. Additionally, these wires are malleable, their lengths unbounded
and direction arbitrary, which leads to a reduction in their subjective clarity; an issue which arises due to
the different programming styles adopted by different developers. These aspects of language design result in
environments which passively permit code that is unclean; algorithmic procedures which though functional
are visually obfuscated, literal spaghetti code. This poses a formidable threat to software maintenance in
the long term, and youll find two main modes of retaliation against this foe; manual cosmetic tweaks in
alignment that border on the obsessive, or automated cleaning tools. In the former case, consistent practice
and sensitivity to code aesthetic must be present throughout the development process, which results in highly
readable and scalable code in exchange for a veritable time penalty. The latter approach of course saves
time, though non-optimal and expansive layouts usually result due to the complexity of placing wire routes
that ideally do not overlap with one-another, as such cases further reduce visual clarity.
Spatial Programming is a graphical programming paradigm that is immune to such issues in representation. What if it were only possible to write code that was clean? To achieve this, we need only introduce

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

a single rule; in order to define dataflow, data terminals must be logically aligned in space. In this regard,
a sourcing terminal is only capable of supplying data to a sinking terminal if they are congruent on a given
axis or trajectory. This approach ensures that executable code may only ever be achieved if the code itself
is consistent with the rules of arrangement prescribed by the language. Similarly, execution priority may be
defined by alignment; arbitrary increments along a single plane for functional nodes permit the definition of
sequential execution, whereas the placement of multiple nodes at a shared co-ordinate range may be utilised
to characterise concurrency. In effect, spatial source descriptions must possess a minimum number of axes
n = 1 to describe either sequential or concurrent algorithms. When visualised, resulting diagrams are thusly
independent of an individual programmers stylistic choice, closely matching the equivalent syntactic rigour
expected by conventional text-based languages. Additionally, in contrast to existing graphical languages,
developers are not required to manually route wire connections as these become an implicit property of the
layout itself. In this regard, we can reason that a spatial approach may also reduce development time by
rendering the process of wiring as an automatic biproduct of positions of entities in the diagram layout,
something that graphical programmers have already specified for decades.
Formally, I define a Spatial Programming Language as follows:
A Spatial Programming Language (SPL) is a programming paradigm that uses the co-ordinates and/or dimensions of abstract structures as a mechanism for describing states of computation.
N.B. The acryonym SPL is not to be confused with the other existing usages; these include the notion of
delegating computation per volumetric units on a processing platform, or toolkits that excel in the analysis
of geospatial data! This is undeniably rather contentious grammatical territory.

4.2

The Punch Programming Language

Well briefly outline some of the formal definitions of the Punch spatial programming language before finally
getting to grips with the graphical implementation (Figure 3). This will involve some discussion of the
languages reliance upon deterministic distribution in order to coerce graphical diagrams into parsable spatial
code. Afterwards, well analyse some the conventions well be using to define sequential data propagation,
memory operations, control flow and concurrency.

Figure 3 A procedural method in Punch.

Figure 4 A punched card.[13]

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

The Punch Programming Language is a cartesian, or two-dimensional, pass-by-value visuospatial programming language styled to imitate tangibility of the iconic punched card (Figure 4). Punch code uses
the dataflow programming paradigm where the diagram layout is used to define the propagation of data. It is
a nested language, whereby the interpretation of computational entities is implicitly governed by their parent
containers in the aggregate graphical hierarchy. This hierarchy therefore defines data scope and visibility,
regions of parallelism and compilation control.
Punch utilises a novel hierarchy implementation that promotes context-sensitive operation, whereby the
interpretation and behaviour of a nested graphical construct depends upon the configuration of its N parents.
In this design route, the graphical components themselves possess no fixed knowledge of their parents and
may only be interpreted as a component within the overarching hierarchical context. This hierarchical
structure promotes a strong relationship between both the computational operation of the software and
also its tangibility, as the graphical feedback of written code to a programmers modification visibly affects
the broader structure of the software layout. In this vein, a programmers interaction with written code
provides advantageous insight to the behavioural operation of an algorithm. This feedback is ingrained
using an event-driven distribution engine which asynchronously manages the spatial layout of the diagram
at development time.
It must be emphasised that a distribution engine is not an essential tool for all spatial programming environments, where dataflow is defined by the alignment of graphical nodes. A spatial programming language
may in fact permit an arbitrary alignment tolerance between successive nodes as a means to determine alignment, which circumvents the issues of a users imperfect placement of graphical icons. In Punch, by contrast,
pixel perfect alignment is a guaranteed property of created diagrams. This attribute was introduced as a
means to promote the readability, consitency and formality of written code which is often bereft in visual
programming.
Usually when orchestrating the distribution of arbitrary and unpredictable layouts designed by an end
user, developers typically implement force-directed graph algorithms[14]. These algorithms model graphical
elements on the diagram as charged objects (or a comparable equivalent) within a periodic physical simulation for a time t. This pattern simulates aggregate attraction and repulsion across the potential grid
until converging to a final potential distribution as t , which produces the finalised graphical layout.
Unfortunately, force directed layouts result in non-deterministic distributions that conspire against the spatial programming paradigm, where positions of elements are essential to the structure of an algorithms
interpretation.
In Punch, we may take advantage of our knowledge that diagrams arent totally arbitrary like that
which force-directed distributions are usually applied; therefore we employ our informed knowledge of the
expected structure of a diagram to distribute layouts in a predictable manner via a bespoke deterministic
distribution engine. This engine makes an analysis of the temporary locations of elements and coerces
them into values that are context-dependent compatible within the language. In these circustances, being
context-dependent prescribes spatial positions and dimensions that are visually conducive to a procedural,
concurrent or type-structured context. The distribution is implemented hierarchically; child-most objects
are given highest priority within the distribution whilst successive parent containers are distributed using the
predicted locations of their children. Using the initial location of an element and its final coerced position
and dimension, the entire distribution of the hierarchical layout may then be packetised and interpolated
between, which exposes a channel of tangibility within the language; different methods of interpolation may
convey information regarding the hierarchical influence on the program. As a deterministic distribution
doesnt depend on iteratively modelling charged interactions, we may describe the behaviour of the layout
manager as event-driven; this is because the layout of the diagram need only be recalculated after it has
been manipulated by the user. In addition to this, nested children within the hierarchy that arent directly
influenced by a modification have no need to be repositioned, as this is instead delegated to the nearest
modified parent in the hierarchy as a means of optimisation.
In procedural regions of code, data propagation using synchronous dataflow is indicated by the alignment

Novel Approaches to Programming Heterogeneous Computational Systems

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

between literal constants and sinking or sourcing graphical icons. Type compatibility, dataflow, loss of scope,
data starvation, allocations and overwrites are represented using coloured cascades. These are analogous to
manual wires used in conventional graphical languages, as by comparison both describe dataflow; however
in contrast, cascades are generated automatically as a biproduct of the memory layout. I refer to these
dataflow entities as cascades because although they describe immediate elements of dataflow, this is a totally
superflouous characteristic in spatial programming! Weve already discussed how dataflow is ingrained in
the diagram layout itself, so in effect a cascade itself is not actually necessary for spatial code; theyre just
mere syntactic sugar. The real responsibility of a cascade is to reflect the successive interactions with a
particular memory allocation, and this is a key difference. Since a memory allocation may persist along an
arbitrary increment of the vertical axis for the scope of the call, spatial programming allows us to visually
embed nuanced information about the nature of interactions with a singular memory address than is possible
with the discrete modes of segmented data transmission used in current visual languages. In effect, memory
allocations that go unused for lengths of the call or unncessary allocations that could instead be made
to overwrite an existing allocation are visually suggested to the user instrinsically due to their graphical
representation. In other words, the conventions of spatial programming graphically promotes memory reuse for the lifetime of a particular allocation; a highly valuable trait when considering that memory is the
bottleneck to modern development![15]
The Punch Programming Language involves the application of discrete interface boundaries used to
segment regions of code. These are referred to as decouplers, as their impact upon the passage of data
and scope of application functionality is respective of their namesake. Within Punch, to declare a region
of increased scope such as a method body or a nested structure internal to a body, we use two mirrored
decouplers referred to as a coupling. These can be thought of as the graphical equivalent to the lexical braces
({}) commonly used in textual programming. The left-most decoupler in a coupling is referred to as a sink
decoupler, which represents the input specification for the coupling. The right-most, representing the output
of the coupling, is the source decoupler. A coupling may be in an open or closed state; when opened, the
internal computational routine contained by the coupling is visible and modifiable to the programmer; when
closed, the source decoupler rests alongside the sink decoupler. When closed, the only information divulged
about the coupling is its interface specification. When a coupling is nested within a region of code, the sink
decoupler expects data cascades to be aligned with the input parameters it encloses, otherwise it is said to
be starved of data. These input parameters are represented using contacts (Figure 5).

Figure 5 A coupling nests a boolean literal which passes data into a contact on a nested coupling.
Contacts are the components of a decoupler that interface with a parent call. These are essentially the
pass-by-value regions for parameter entry when sinking data, or the entities that write pre-allocated data to
a parent cascade when sourcing. All contacts possess a two data types; a sinking data type and a sourcing
data type. This is because depending upon the perspective, a contact can be thought of as an input which
samples the data at an aligned cascade and also the driver to an underlying routine. This notion is reversed
for contacts that act as data sources on the source decoupler. The instance where non-uniform data types
are maintained using a single contact is for privileged types that engender control flow, such as the special
iteration contact, which sinks a boolean value and sources an integer representing an auto-incrementing
loop count (Figure 6). Contacts, in accordance with all programmatic components of Punch, undergo
alignment with the fixed vertical increments of the memory axis. In order to pass a single cascading data
source into multiple contacts within a single decoupler, two or more inputs may be aligned to a single vertical
index provided that they are all root-most type compatible with the driving cascade. This is the spatial
equivalent to a crossed wire in graphical programming, which we refer to as imbrication. Imbrication may

Novel Approaches to Programming Heterogeneous Computational Systems

10

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

only be applied to atomic decoupler types as interface contacts for a coupling must represent isolated memory
regions, or unique cascades. It is important to note that cascades may exist only within synchronous regions
as the lifetime of the source memory locations they represent are in direct correlation with the duration of
a synchronous routine.
Decouplers may exist as their own finite programmatic constructs within Punch, in the form of invocations,
axioms and facades. These all represent atomic interfaces with a programmatic operation with respect to
the caller or implementor. An invocation is used to make a call to a predefined method body, an axiom refers
to a core indivisible programmatic operation within the language or hardware platform (well discuss this at
great length in the following chapter!) and a facade represents the parameter declaration for a method akin
to C s function prototype or Javas abstract declaration.
A coupling may be used to represent a method declaration in Punch. When resting within a class definition (when a
class container is the direct parent of the coupling within the
graphical hierarchy), the coupling may be treated as a callable
method that belongs to the owning class. These method dec- Figure 6 An iteration contact accepts a
larations may be called inline using an invocation decoupler, boolean driver and sources an integer to the
which carries a strict reference to the coupling it invokes. The nested call.
invocation holds an array of contacts which persists the declaration of the method. The contacts are used as an interface to the master method call and similarly holds a
reference to the corresponding contact in the declaration.
Concurrency within Punch is defined using concurrent parent containers. Currently, these have no
graphical distinction versus sequential regions. In contrast to sequential regions, there is no implied order of
execution between the concurrent containers due to the inherent asynchrony of simultaneous execution. In
accordance with the spatial programming specification, the horizontal locations of nested procedures within
a concurrent context are all equal. This implicitly denotes that each procedure executes simultaneously. As
a means to share data between these distinct separate processes of whom are totally agnostic to dataflow,
any data fed into a concurrent region becomes accessible via the parameter list of all nested calls. In
order to promote consistency with the data passed into the concurrent call, the vertical locations of the
nested calls must match those of the driving cascades in an effort to improve readability. This is a useful
property to enhance our insight into the dynamic nature of the language; whenever a new call is placed
within a concurrent region, all data terminals available to the concurrent context must be assigned to the
nested procedures dynamically. Likewise, if the vertical order of the parameters are changed on the master
concurrent container, the order in the parameter lists for all nested children must be updated accordingly.
In this context, cascades are not generated since the direct children to the current container do not operate
using conventional dataflow; they rely upon shared variables. Shared variables may be passed using contacts
defined on the sink decoupler of the concurrent coupling; these are then dynamically persisted on the input
boundaries of the nested couplings that execute concurrently with one another (Figure 7). Each nested
coupling may be thought of as its own independent process, and the lifetime of the concurrent coupling in
a procedural context is persisted for as long as any one of the child couplings are still active. This structure
permits asynchonous event data to trigger simultaneous processes for the lifetime of a concurrent task.
Punch is an object-oriented language, therefore in addition to primitive data types, developers are permitted to define their own custom container types as a means to logically segment and encapsulate regions
of code. These object-oriented containers, used to encapsulate member variables and procedural method
calls that may be invoked, are represented using concurrent regions to highlight the random-access nature
of variables and methods belonging to the class with respect to the caller. The language aims to offer conventional object-oriented programming paradigms such as inheritance, though at this stage in development
we are limited to procedural program descriptions only.
A desktop graphical diagram in Punch consists of a minimum of a single main method, used as the
entry point for program execution. On a diagram consisting of no runtime targets, the main method is

Novel Approaches to Programming Heterogeneous Computational Systems

11

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

implicitly designated to execute along the development machine. Conversely to this, developers may supply
additional runtime targets, represented as programmatic objects, each nesting their own respective entry
points. These entry points may vary depending on the execution architecture; for example, some platforms
such as GPUs usually dont expect single main methods, but multiple shaders instead. A runtime target,
in addition to behaving like a static object, is used to implicitly control the means of interpretation and
describe the compilation chain in correspondance with Punchs hierarchical aggregation approach. Similar
conventions are applied to peripheral devices, which may act as member variables of a runtime target or
shared variables to the wider system for multiple access. The library of available functions in a particular
development context is also filtered by the runtime target, therefore only supported operations within a
particular execution environment may be utilised.
Through the grouping of an application into its respective
runtime platforms, its possible to visualise the hardware or
virtual platforms within a heterogeneous system and their interactions on a single diagram, increasing the simplicity of representation for an application in its entirety. This design choice
aims to suppress the convention of segmenting whole applications into separate distinct projects by the runtime platform
which has been so widely embraced by contemporary system
design.
Figure 7 Two concurrent processes have
access to two shared variables defined by
4.3 Heterogeneity and the Principia Mathe- the surrounding coupling.

matica
Luckily until this point in this work Ive been able to skirt
around the fringes of the most substantial claim made in this report; the supposition of a novel method of
programming with an unparalleled level of agnosticism to the runtime platform. When I say this, Im talking
about an approach to defining computation that truly doesnt care about what it executes upon. Now, this
is quite a statement; as we know, system architectures vary enormously! Were not just talking about
differing kinds of instruction sets (digital representations a computer uses to describe a series of operations)
but vastly different runtime environments ranging from microprocessors and web browsers to the massively
parallelisable sea of logic gates inside an FPGA, not to mention all of the computational platforms which as
of yet dont even exist. As an analogy, Im supposing of the programming equivalent to a speech interpreter
who was capable of speaking every language that there ever has been, or ever will be, with the utter fluency
of a native speaker.
Ideas for this approach stem from those taken in Betrand Russell and Albert Whiteheads early twentieth
century works the Principia Mathematica, or PM. In PM, Russell aimed to reconcile all formal works in
symbolic logic to achieve total completeness and coherence with proven mathematical theorems. In effect,
he created a rigourously defined logical system that possessed a uniform relationship to existing proven
mathematical theory (and ambitiously, that not existing!). This system relied upon a few core principles,
referred to as axioms, which when combined would produce a progeny (or first generation) of higher level
mathematical functions. These could be combined arbitrarily, producing a second generation, or a third;
producing increasingly higher level computation that could in effect be broken down into to just a handful
of key rules. Its my initiative to use a similar notion in the field of heterogeneous systems; expressly, is it
possible to build an expressive and performant programming language that relies upon as few programmatic
axioms as possible?
I must mention two existing schools of thought on this matter before continuing. In terms of describing
digital logic, the pervasive fundamental mode of computation by which our technology is described (at least
until quantum computing becomes a viable alternative and not just the plaything of theoretical physicists),
there is an idea of logic expression analogous to that of PM. This idea is known as De Morgans Law. This

Novel Approaches to Programming Heterogeneous Computational Systems

12

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

rule proves how any boolean (true or false) operation, irrespective of complexity, may be composed of a
single operation; the two-input N AN D (Table 1)[16].
A
0
0
1
1

B
0
1
0
1

C
1
1
1
0

Table 1 Truth table for the two-input N AN D. Binary drivers A and B result in output C.
Different combiniations of N AN D gate circuits may be used to emulate any other kind of higher level
boolean operation such as N OT , OR, AN D, XOR. These higher level functions, analogous to PMs progeny,
may then be used to describe arbitrarily complex combinatorial logic such as a step through the calculation
of some floating point mathematics or a singular stage of a finite digital filter. To emphasise the applicability
of this law, it is not uncommon for user-programmable devices, which are often taken advantage of for use in
arbitrary consumer-defined applications, to consist entirely of N AN D gates! Provided we make the common
case fast by improving timing characteristics of the transistors which implement the axiomatic N AN D gate,
these devices often prove very performant. This is an important optimisation step which has significant
impact on some aspects of our later discussions.
The second school of thought, rising up from physical digital gates to the philosophical execution of a
theoretical machine, is the Turing Machine thought experiment[17]. Alan Turing, known as the father of
modern computing, supposed of an imaginary machine to reason about his theories in computation. Given
the historical bottlenecks to calculation speed and memory, not to mention size of room required, the runtime platform by which Turing envisioned the implementation of his hypotheses in computation was capable
of existing only within his skull. This experiment states that the theoretical machine is in possession of
unbounded memory persisted by an infinitely long spool of modifiable memory cells, whose contents may be
read and conditionally acted upon. Turings mental experimentation validated that his machine needed only
two fundamental capabilities in order to describe any possible algorithm in computation, a categorisation
which later became known as being Turing Complete:
(1) The ability to modify a memory address. (2) The ability to act conditionally.
Astonishingly, these are indeed the only attributes required in order for a computational device to be
capable of carrying out any possible task in computation. In terms of establishing concurrency, the ability
for a computer to perform actions simultaneously using mechanism commonly referred to as threads and
processes, Turings approach need only be refined via the instantiation of multiple Turing machines. In
modern day analysis, a machine or language is considered Turing Complete if it is capable of simulating any
single-taped Turing Machine.
Turings deeply non-obvious approach to defining computation has inspired development in the field of
One Instruction Set Computing (OISC), where entire architectures of computation and suprisingly even
whole operating systems may be comprised of a single executable command, provided the command itself is
Turing complete[18]. As an example of this we may take the SU BLEQ instruction, which both subtracts a
value from a memory address and performs a conditional branch if the result is less than or equal to zero.
This single instruction may then be used to model higher level operations through the implementation of
compound instructions, shown in Listing 1.
#subleq A, B
#uses internal accumulator acc
#mem[A] = mem[A] acc
#acc
= mem[A]

Novel Approaches to Programming Heterogeneous Computational Systems

13

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

#if (mem[a] <= 0) goto B


ADD a , b == subleq a , Z # mem[Z] initialized to 0. mem[Z] = mem[a]
subleq Z , b # subtract a from b. mem[b] = mem[b] + mem[a]
subleq Z , Z # restore mem[Z] == 0.

Listing 1 A compound addition instruction comprised only of calls to the SU BLEQ instruction.
Id like to draw your attention to the core characteristic each of these patterns have in common with one
another; this notion that iterative levels of complexity may come to fruition out of just a tiny group of core
functions. Its this sort of thinking that Id like to apply towards our contemplation regarding heterogeneous
computation. Were all very well versed in the individuality of programming languages and the idiosyncracy
of runtime platforms, and to suggest otherwise would be totally disingenuous. The sheer scale of engineering
constraints ranging from power to performance and from cost to competitivity are tangible enough evidence
for this diversity alone. Yet again, I find myself forced to bear the role of devils advocate and ask you to
consider the following assertion. I state that unquestionably, all of our programmatic conventions in software
and hardware design are based upon discrete boolean logic; even the continuous range of truths conveyed
by fuzzy logic systems encode their degrees of truth using a finite digital representation! In making this
assertion, this expansive field filled with diverse and mostly unreconcilable architectures suddenly appears
to be a little less expansive and a little more reconcilable. Weve introduced a commonality, and we may
add many more at our whim. With regards to the languages we use to control these machines, we may infer
similar kinds of commonalities; provided they possess some core functionality by which we compose all of
our logic, we may surely reconcile them.
Youll have to forgive me for growing abstract, but ruminations regarding commonalities often tend to
quickly grow philosophical. What Im trying to drive at is whether we could structure a programming
language that maintains a persistent and dynamic catalogue of these commonalities? If the core structure of
the program were designed in a way that a platform-specific features could fit in like the piece of a puzzle?
If entire operating systems may be built out of the SU BLEQ instruction, then why not a programming
language? I propose that Punchs library of functions may equally be composed of a set of core axioms, just
like those envisioned in PM. What Im suggesting is that the whole library of functions available to the user
could be fundamentally comprised of a call to a N AN D gate. In effect, every description of computation in
the language may be iteratively broken down into successively lower levels until the underlying architecture
consisting only of the humble digital gate.
How does this approach achieve heterogeneous system programming? In truth, it does not; and this is a
key concept that lies at the very core of Punch. We cannot possibly ignore the fact that execution platforms
are totally and utterly diverse in their implementations, and such configurations cannot be innately known
by the language a priori. Further to this, we cant just expect to define an axiom set specification and hope
that hardware developers will follow it either; this would place a heavy constraint not only on them but also
on the viability of the language to existing platform architectures. The method by which I hope to achieve
hardware agnosticism is as follows; just like the core axioms of mathematics are taken as absolute truths,
we expect that the single core axiom of Punch is taken as a universal truth too. As soon as we guarantee
this, down falls the whole house of cards. Every conceivable algorithm written in Punch becomes readily
available on any target platform effective immediately, provided were able to keep our promise.
The remaining question; just how may we define the truth of an axiom? The answer is relatively simple;
this is an aspect of the Punch programming language that we open source. Each time new hardware comes
along, or a novel instruction set, all we must do is specify how to compute the N AN D operation within that
context. Provided we catalogue these implementations openly, truly hardware agnostic programming may
become a viable reality. Theres little new about this kind of approach, though theres a very clear reason why
its never been taken seriously before. Weve seen that to build complex functionality out of core commands,
it takes multiple calls; this slows execution when compared to a native invocation. If we think in terms of
Novel Approaches to Programming Heterogeneous Computational Systems

14

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

mathematics, its perfectly possible to replicate floating point computation using the SU BLEQ function
alone, but the performance of such an implementation would be without compare to that of a floating point
arithmetic logic unit. Its not a performant solution, and performance is one of the biggest drivers of all for
heterogeneity itself. What I propose is that platform diversity doesnt have to be a hindrence at all; in fact,
quite the opposite. It can be something that we truly take advantage of.
As this chapter draws to a close, mathematically inclined readers may find it encouraging that I return
back to our discussion of the Principia Mathematica. Wherever mentioned, the subject of PM quickly turns
towards a talented mathematician by the name of Kurt Godel; the man who single handedly brought the
most rigorous and concise definition of mathematical theory in history down to its knees. Godel, inspired
by the recursive definition of numbers comparable to that of the Fibonacci sequence, vied to replicate
PMs axiomatic symbolic logic using analoguous unique integers composed of prime numbers. Using this
convention, axiomatic symbols may be regarded as the seeds of the sequence and the rules of inference
comparable to its incremental progression. This inspired notion highlighted PMs greatest flaw; namely,
that the system could be proven inconsistent, and subsequently irreconcilable with that of ideal formal logic.
By means of analogy, G
odel had effectively proven the statement I am unprovable within the frameworks
of PM, which triggered devastating and far reaching repercussions ranging from the abandonment of PM to
rousing wide suspiscion whether the infamous Fermats Last Theroem could ever be solved at all[19]. Now,
Punch has adopted a similar convention; it too will be comprised of compound axiomatic calls and is therefore
at risk to issues of uncertainty; though we must impose a stark contrast. Where Principia Mathematica was
proposed as a means to an end, as an expression of total harmony with proven mathematical schools of logic,
we cannot apply the same reasoning to Punch. Weve all found that in practice, wherever we build iteratively
complex routines out of core lines of assembler, these fundamental matters of uncertainty hardly fall into
question (though Turing was capable of demonstrating programmatic uncertainty in a programs inference of
its own ability to terminate, known as the halting problem). This the calls we make are in a sense utter truths;
these are not the outlying philosophical assertions that rest at the very core of universal formal logic, these are
but the oaths of the target execution platform. The language is a symbolic intermediate representation; not
the core means of execution, unlike Principia Mathematica, who may act as both narrator and manipulator.
In this regard, provided the execution of the software definition is implemented precisely, without risking
global hazards, we may succeed. To hedge our bets, we may regard the undecidability of the proposed
frameworks as comparable to those of lambda calculus (-calculus), which shares many commonalities with
programmatic computation [20]. After all, -calculus is in itself capable of simulating the single-taped Turing
Machine! With this disposition, the undecidability of Punchs implementation lies amidst the impossibility
of detection of the computational equivalence between two expressions; this is due to the fact that it has
been proven to be impossible to establish a function that decides upon the equivalence, outlined in a proof
very reminiscent of the works of G
odel. In the following chapter, we will discuss how the formalisation of
strict invocation protocols may allow us to circumvent these issues in axiomatic representation.

4.4

Superseding, or Having our Cake and Eating It

The thought experiments provided by Turing and the existence of single instruction computing plays an
invaluable role in my assumption that achieving heterogenous computing may just be a matter of a selection
of the appropriate axioms, provided the overarching software structure is generic and flexible enough. As
weve seen, arbitrary and rich functionality may be achieved using a small subset of functions, though at
a veritable cost in performance. Weve shown that even a small operation such as an add is costly when
implemented as a compound instruction that desperately masquerades as its native equivalent.
As hinted at earlier, a core feature of Punch is that it is a dynamic programming language. This
means that the core modes of operation in how the language is processed may be overrided arbitrarily. This
interchangeability has so far been proposed as a mechanism for achieving heterogeneous computation through
per-platform axiom specification, but this is just the icing on the cake. The true benefit to this approach

Novel Approaches to Programming Heterogeneous Computational Systems

15

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

only comes into light after we consider that we can apply this process of custom behaviour supplication
towards any aspect of the programs runtime interpretation. This is a process that Ive come to refer to as
superseding.
Lets look back at that costly compound function. Supposing that if we were targeting a device which
possesses a native addition instruction, in Punch were at liberty to specify that wed prefer to use the native
implementation instead of the emulated counterpart. We may take the platform-independent graphical add
function that is internally comprised of numerous axiomatic calls, and supersede its original definition with
something more succinct (Figure 8). In doing so, at compilation time the superseding definition will be
preferred over the compound block implementation. Futher to this, every other higher level operation that
makes a call to this function is also implicitly improved by the definition. Here I must emphasise the enormous
potential performance gains to this approach, in reminding ourselves that every single computational function
will be effectively modelled on the gate level.

Figure 8 A graphical block in Punch may be superseded using conventional source languages. (Verilog)
Were permitted to apply the process of superseding to Punch code arbitrarily. Given that superseding
takes place at the invocation level, underlying graphical code involved within the call need no longer be parsed
as it becomes irrelevant to the compilation. This segmentation mitigates the overlap between recursive call
implementations and superseded blocks, and emphasises the importance of a superseding element behaving
precisely as expected. Using this approach, applications within Punch may subsequently be built out of a
mixture of the environments compound axiomatic calls and more performant superseding platform-specific
bodies of code. A given platform or base language implementation may in this regard be iteratively tuned
and improved for its lifetime.
This approach necessitates behind-the-scenes stitching of these different implementation types in order to
produce programs that are executable. In this avenue of design, the definition of compilation modules used
for describing the translation between end user submissions and Punchs compiler must be established in
order to formalise the interface between the two. Using object-oriented inheritence, where a programmatic
struture may be treated like a generic component, its possible to describe a base compiler interface type
that may be uniquely overridden for various forms of superseding sources to improve both the flexibility and
simplicity of integration. Undeniably, the bottleneck to this proposed approach in heterogeneity has to be
the interface specification itself. In other words, the software fingerprints left behind by Punch as it weaves
superseded method calls together will be manifest in every single application it produces, and this is the
unavoidable difference between true native code and Punchs equivalent. To further elaborate on this point,
well discuss the fact that Punch is a pass-by-value programming language, which means that a local copy of
all source data is made whenever it is passed into a function, ensuring the source data itself is left unchanged.
This is the selected methodology because it possesses an intuitive natural resonance with the underlying form
of graphical programming, and matches the conventions used in the language used to build Punch, Java.
When compared to a pass-by-reference language, where the source data is manipulated directly, pass-by-value
necessitates a greater memory overhead per method call[21]. We must remind ourselves that executable
blocks may be overridden by code which uses the pass-by-reference paradigm. In this line of reasoning, its
vital for us to ensure that superseding is conducive to performance by utilising a pass-by-reference interface
between compatible superseded calls wherever possible, which necessitates a layer of abstraction between the
logical implementation of a superseded function and the memory allocations made at the boundaries of an
invocation. Well later discuss how the segmentation between memory and computation is a natural theme

Novel Approaches to Programming Heterogeneous Computational Systems

16

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

in generic programming.
Id like to take a brief moment to meditate on this tangential approach to programming. Modern
software development has an innate dependence on collaboration; where concepts, design patterns, libraries,
troubleshooting and custom solutions may be freely sourced by scores of online communities. Since were
fundamentally talking about code sharing, if Punch were indeed capable of cataloguing platform-independent
solutions, this talent could be applied to optimisation and broadening platform support. In this respect, the
notion of open source superseding is viable provided that the incentive of hardware agnostic programming
is tantalising enough.
Having reasoned about the viability of axiomatic descriptions of complex functions, its imperative that we
now theorise about supersedings applicability to memory and control flow. The ability to act conditionally
or dynamically allocate memory on the fly are extremely potent attributes of modern computing. These
features are used so extensively that additional mechanisms such as memory caches and branch prediction
tables have gained great prominence. When thinking hetereogeoneously however, we quickly hit a formidable
stumbling block; the capabilities of platforms with regards to memory and branch behaviour is largely
diverse. Its Punchs role to treat low-cost embedded microcomputers, conventional desktop machines and
high-performance devices with utter leniency; and this poses some characteristic problems.
Memory is of particular difficulty to orchestrate in the design of axiomatic code descriptions, because
memory interaction persists not only in runtime dynamic allocations and static source descriptions, but also
at every method invocation due to the selection of the pass-by-value design. In this light, the simplicity
of the N AN D solution may be called into question; after all, both of the input signals need be in effect
replicated to coincide with the intended interface specification. In turn, this greatly increases the base
overhead of a call to the axiomatic block. When exporting to high-level languages, persistence of passby-value behaviour may either be integral to the construction of the source language, or otherwise easily
emulated. By contrast, hardware description languages may feign pass-by-value via the deployment of
registers at call boundaries that latch onto the input parameters upon synchronous invocation. Dynamic
allocations, however, do pose a threat to the heterogeneity of an executable specification. For instance, finite
resource devices such as field programmable gate arrays are in this respect totally impotent; after all, a
dynamic allocation in the context of these devices would be physical runtime gate synthesis! Conventionally,
engineers circumvent this limitation by making dynamic allocations via physical devices such as internal
block RAM accessible through vendor libraries [22], external high-speed memory modules, or in the worst
case, resource-inefficient synthesised RAM[23]. Its plausable that we too may adopt this flexible approach
in Punch, but in doing so, we impose a very grave burden on our routines; namely, that they must have
an explicit awareness of the dynamic memory resource a priori. Its important that we take a moment
to expand upon this point, and just why its so detrimental to heterogeoneous design. Lets take Java;
the underlying language by which the conventions of Punch are described. Java is a platform-indepent
programming language which assumes that all compiled Java code executes upon the Java Virtual Machine
(JVM). This ingenius approach to platform-independent computing assumes the following; all target devices
possess a compatible implementation of the JVM, therefore all calls made by the runtime software are
guaranteed to work seamlessly on the runtime platform [24]. Provided Java code is converted into platformindependent bytecode, a custom binary representation, platform-independent computation is assured. This
methodology is analoguous to Punchs promise that the axiomatic gate description is a platform-independent
dharma. The JVM by extension is also capable of assuring dynamic allocations; programmers may allocate
contents to a resizable Java array arbitrarily, that is until the JVMs runtime-specific stack depth is exceeded.
Programmers need only access the resizable memory resource using high level calls; they are not expected
to care about the underlying memory implementation which is managed independently. However, this is not
practical or suitable for all use cases in embedded systems, where memory management must be stringent. In
terms of superseding, dynamic allocations may be circumvented by writing to fixed pre-allocated resources,
though this increases call overhead and introduces a level of deviation from the goal of consistent platformindependent execution. The ugly truth is, like an instruction language, the memory architecture of a target

Novel Approaches to Programming Heterogeneous Computational Systems

17

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

device must be treated with an equal if not greater level of suspicion! This is due to the fact that although
the instruction set remains fixed or a given target platform, memory is permissably more flexible than that.
To enhance our appreciation of the sheer difficulty of our predicament, well turn our attention to timing.
In high level execution environments, developers may succeed without ever having been aware of such a
peculiar entity as a clock signal; conversely, this is a critical resource for systems engineers who regularly
analyse the distribution of clock domains through low latency distribution networks across highly parallelised
chips. These lines in effect persist the mass order of a device-wide system without risking metastability, the
logical glitches which conspire against the analogue quality of digital signals. Clock sources and distribution
are conventionally handled on the register transfer level, which is analogous to the representation used in
Punch. It follows logically that in order to engender flexible platform-independent programming, developers
must be at liberty to define the clock distribution for particular regions of code or invocations. Due to the
timing constraints of engineering domains highly dependent upon synchronization, such as communications,
it is also essential to provide programmers with the capability to allocate their own software-defined scaled
clock implementations using clock divisors or utilise hardware-defined phased lock loops.
In low level digital design, complex algorithmic behaviour depends not only upon combinatorial descriptions of computation that we guarantee using the axiomatic N AN D gate, but also time and state. This is
referred to as sequential logic, which necessitates a reference to a periodic bistable clock source. This strict
and unavoidable reliance has serious consequences for our definition of a platform-independent programming paradigm, which may be contextualised in the following scenario; suppose that we define a sequential
algorithm on a desktop machine that accepts a single boolean input parameter (Figure 9 (Left)). On
a clock-driven runtime target such as an FPGA, this sequential function would expect a boolean input
parameter and an additional clock reference! (Figure 9 (Right))

Figure 9 (Left) A sequential execution path dependent on boolean input parameter. (Right) The sequential
method expects an additional clock parameter within low level execution environments. This parameter,
rendered using a void event type, lacks a driver and is therefore starved of the input data. This in turn
causes the diagram to be no longer synthesisable or platform independent.
This discussion brings to light that when establishing platform-independent computation, even when
packaged as reusable blocks, there is still an innate reliance upon hardware-specific attributes when constructing memory or time dependent processes. My proposed solution to this great architectural disparity
comes again from the world of object-oriented programming, namely, the way that classes may be defined to
inherit properties from parent classes in an object-oriented language, the same principle could be applied to
function definitions within Punch; or, more accurately, their parameter declarations. I posit that a function
definition in Punch can be used to define the input and output terminals for conventional dataflow like
any other visual programming language, but in addition to this, the method may be detailed to implement
additional invocation properties. Were used to similar conventions in object-oriented programming; after
all, method declarations are often subject to rules of protection, overridability and mutual exclusion. I propose that we declare additional runtime-specific qualifiers that dynamically modulate the parameter lists for
function invocations at the precompiler stage.
Allow me to further elaborate on this idea. Given that branching behaviour such as looping or conditional
execution are all types of sequential logic, we can state that all function declarations that contain control

Novel Approaches to Programming Heterogeneous Computational Systems

18

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

flow parameters may in turn be qualified as sequential methods, in the same way that we might say that a
group of methods that may only be invoked by an owning class have private visibility. By logical extension,
well also state that any methods which nest sequential logic in their internals, by invocation or otherwise,
are in unto themselves sequential. Now, we havent made any changes to the parameter interface at all,
weve just made an assertion; therefore the platform-dependent invocation errors shown in Figure 9 are
still very much a detriment to our goal of heterogeneous computing. However, when we come around to the
interpretation of function declarations, the qualifying attribute of whether a call depends on a sequential
driver such as a clock signal may be left up to the interpreter. The resulting design permits that desktop
execution of a sequential function must only depend upon the variable dataflow defined in the graph; whereas
compilation aimed at an execution platform such as an FPGA may react to the sequential declaration and
know intrinsically that a clock reference must also be provided. This approach ensures that all code and
routines may look identical irrespective of the target platform, which subsequently increases the cohesion
between development on wildly different system architectures. Therefore Figure 9 (Left) and Figure 9
(Right) actually become synonymous!
What were essentially doing is performing hidden dataflow; this can be likened to the imaginary axis
of a spatial programming language. In specific terms, Im asserting that all sequential calls within Punch
implicitly possess a hidden parameter that expects a periodic event source for trigger logic. When routing
this source throughout subsequent sequential calls, we expect that all of these background terminals lie on a
congruent axis, thereby avoiding starvation, whilst being managed by the graphical compiler transparently.
As a platform class definition will be contractually obliged within the language to define a base clock signal,
the compiler may use this reference to initialize the distribution chain and subsequently clock all operations
throughout the entire design hierarchy. In a similar manner, a superseding interface for a method dependent
on sequential logic may be dynamically passed a clock reference for a given superseding source type. In
real terms, this would enable a lexical superseding source such as Verilog or VHDL to integrate with the
wider applications clocking architecture via their module declarations. This would impose strict handling
conventions defined within the language specification i.e. naming, type, direction, usage etc.
Well summarise this approach by outlining how these hidden connections are prioritised. We discussed
earlier that in some cases its necessary to define custom trigger sources to drive sequential logic, as this is a
pressing concern for applications with strict timing and synchronisation requirements. Rather than limiting
clock distribution to the base system clock alone, Punch must also permit developers to select an arbitrary
driving clock at their own discretion. Sequential function invocations may have their hidden clock source
parameters made visible and therefore assignable on the graph, provided theyre within a suitable hardware context. This assignment will subsequently drive all nested invocations within the execution hierarchy.
Readers familiar with digital design will be wary of this assertion, since such an approach risks data hazards
and synchronization whenever we cross over clock domains, especially in the midst of clock skew arising from
long combinatorial paths. However, since it is possible to detect competing clock specifications between mutually dependent sequential sources, buffer stages between the two domains could potentially be dynamically
allocated at the compiler level to mitigate the effects without harming the agnostic representation of the
software.
The conventions for establishing imaginary axis style precompiler interpretation of diagrams may be
extended through the definition of additional method qualifiers. This convention should ensure that the
execution of functions for arbitrary platforms should be assured, as we may compensate for platform-specific
idiosyncracies arbitrarily. This approach should permit platform-specific implementations of the axiomatic
N AN D gate, memory interaction, static hardware utilisation and branching to be utilised effectively.
When generating executable code for a target device, Punchs platform-independent graphical routines
must to be converted into native architecture-specific binaries. Weve shown how a platform type definition
is used to encapsulate the responsibilities of virtual behaviours in the language, but in addition to this,
they may also exert control over the compilation chain in numerous ways. The most immediate impact
of this authority is the assertion of underlying code representation, where the generated output source of

Novel Approaches to Programming Heterogeneous Computational Systems

19

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

the compilation proess may be represented using a specific lexical source language, assembler instructions
or external library calls as defined by the platform. The generated output of this process is therefore not
a compiled program, but an intermediate representation that is capable of being fed to platform-specific
compilation tools. By contrast, this intermediate representation is in fact the primary representation in
conventional programming environments.
A goal of this research is to limit the number of design tools required in heterogeneous system development, where conventionally a distinct development environment is required for each respective target
device. This is an accepted shortcoming of increasing hardware diversity to meet performance requirements
through multiple device vendors, who usually provide environments that abstract the internal programming
specification from consumers using bespoke compilation tools. This approach is of particular importance to
manufacturers that wish to maintain secrecy regarding the programming methodology. A biproduct of this
convention is a ripple effect where source files have grown dependent upon manufactuer-specific syntax and
are a far cry from open standards specifications, inflicting a great impact upon application diversity. This is
because the algorithmic specification becomes vendor defined and in turn it grows impure. This implicitly
devalues it; cost and risk becomes deeply intertwined with that of the manufacturer, and its portability
is harmed. This convention isnt set out purposely to burden developers, though imposed reliance and increased familiarity with vendor tools is in my mind undoubtably a marketing invention; but because these
environments do simplify the advantageous utilisation of core hardware features. Simply put, many modern
platforms provide features which just do not exist in highly generic open programming language specifications. In this regard, if we want to make performant heterogeneous programming a reality, our hand is
forced. Within Punch, these vendor-specific operations may be integrated within compilation submodules
due to the overridable nature of its interpretation, though the caveat to this is of course a compatible
superseding library must be included alongside the submodule as a means to persist logical and error free
integration. If the superseding module depends upon a fixed exclusive resource, its utilisation must be
tracked and governed effectively. In this regard, Punch aims to shoulder the burden of manufacturer risk by
placing vendor-defined calls within modular and disposable superseding blocks.
Platform-specific information may also provide feedback to the development process; the accessibility of
certain functions, for example, may be limited dependent on the execution context. By means of example,
this convention could be applied to the management of timing and synchronization calls depending on the
resolution of the target platforms base clock. A similar convention may be applied to core constructs
within the language such as concurrent execution containers, since these are not directly applicable to single
logical thread devices such as basic microcomputers, though these may feign concurrency using event-driven
interrupt handlers. Due to the abstract nature of Punch, it is reasonable to suggest that a virtual machine
implementation capable of sharing cycles between discrete processes could be executed on a single-threaded
computing platform as a means to feign support for concurrency.
The superseding architecture at this stage may sound a little farfetched, so I hope to comfort the reader
in explaining that it does in fact exist! Currently, the architecture is a proven component within the existing programming frameworks; graphical cascade generation, dynamic type propagation and logical integrity
checks via simulation all capitalise upon our ability to supersede the basic foundations of the Punch interpreter. This is possible due to the fact that the superseding module abstracts key characteristics of the
runtime layout to allow trivially simple analysis and consistent handling. In broader terms, the personality
of the language itself, is built on our ability to supersede at our whim!

Novel Approaches to Programming Heterogeneous Computational Systems

20

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Punch Programming Language Specifcation (2016)


Graphic

Name

Description

Decoupler

Interface boundary between execution


paths. Enforces a memory allocation for
nested parameters using pass-by-value.
When isolated, represents an invocation.

Coupling

Encloses an execution path using a Sink


Decoupler and Source Decoupler. Nests
encapsulated code. Represents a
declaration when residing on a class level.

Boolean Literal

A boolean constant. Initializes a data


index to the displayed value for the
length of a cascade.

Uninitialized 1D
Array

Array literal, zero element.

Feedback

Writes to a congruent Tunnel on a Sink


Decoupler on each execution pass. Data
type is assigned by the Tunnel.

Iteration

Defines bounded and unbounded


iteration across a nested region.

Selective

Conditional execution branch. Selects


one of the nested internal execution
paths of a coupling at an index
corresponding to the driving value.

Event

Asynchronous event trigger. Enables


execution for processes nested within a
concurrent context.

Tunnel

In a sinking context, allocates a memory


buffer initialized to the driving source
data. Writes to a data index in a
sourcing context.

Table 2 Core procedural programmatic elements specification as of 2016. (Part A)

Novel Approaches to Programming Heterogeneous Computational Systems

21

University of Manchester School of Electronic and Electrical Engineering

Graphic

Name

Alexander Thomas

Description

Selective,
Boolean

Conditional contact, type-propagated to


accept boolean data. F ALSE executes
the first case within the coupling, T RU E
executes the second.

Boolean Array

A boolean array literal, initialized using


four boolean constants.

Tunnel, Boolean

Tunnel contact, boolean


type-propagated. Uses pass-by-value
allocation for the scope of the parent
coupling.

Iteration, I32

Iteration terminal, boolean type


propagated. Causes unconditional or
skipped execution of a couplings internal
execution path. Sources the iteration
count for the scope of the coupling.

Iteration, 1D
Array

Iteration terminal, one dimensional


boolean array type propagated. Iterates
the couplings internal execution path for
the number of elements contained within
the array. Sources array index.

Cascade,
Starved

Represents a starved data input


parameter. Witholds diagrams from
compilation. Colour indicative of
required root data type. Disables
compilation.

Cascade,
Erroneous

Represents the existence of a sourcing


and sinking connection between
incompatible data types. Disables
compilation.

Cascade,
Overwrite

Discontinuities between sourcing types


on a shared index represents an
overwrite. The preceding source type is
destroyed.

Concurrency

Spacing between couplings signifies


threaded execution. Parameters are
dynamically assigned and ordered with
respect to the parent coupling.

Table 3 Core procedural programmatic elements specification as of 2016. (Part B)

Novel Approaches to Programming Heterogeneous Computational Systems

22

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Further Work

At this stage, the basic graphical constructs and programmatic elements of the language have been implemented and verified via simulation. In future, great emphasis will be placed on developing rich functionality
using the core axiomatic block implementations. This will involve production of the progeny of boolean
functions, succeeded by second generation integer and floating point mathematics libraries. The performance of these tools via simulation will then be benchmarked using a computationally intensive application
to compare core and superseded implementations. The development environment will be ported onto a mobile device as a means to creating an interface system that is most conducive to spatial programming and
forego the existing bare bones static menu implementation. Importantly, Punch has been theorised as an
object-oriented language from the outset, as key properties such as inheritence and encapsulation are vital to
the formuation of per-platform, per-source and per-vendor compiling specifications. A platform-independent
mechanism for describing, storing and interacting with user-defined object types must be researched to make
this feat a reality. Finally, the superseding architecture must be applied to the generation of target-device
specific compilation constructs via a server-persisted catalogue in an effort to minimise the developmental
overhead in programming diverse and unique system architectures.

Conclusion

We have tread expansive ground in this report, so before coming to a close Ill summarise the main themes of
this report in an effort to tie everything together. Weve argued that the field of programming has as of yet
not taken full advantage of the wide availability of powerful mobile devices, reasoning that the ubiquity of
touch screens and disproportionate preference towards textual programming languages just arent compatible
enough to be treated as a viable option for realistic development in scientific and engineering applications.
Weve suggested that the reality of mobile programming necessitates a graphical language compatible with
touch interaction that simultaneously circumvents some of the most significant drawbacks to widely adopted
conventions in graphical programming. Weve discussed an alternative language, a novel graphical spatial
language, as a mechanism for writing code that is robust to the high imprecison in touch screen interactions,
that applies dynamic distribution at development time as a means to safegaurd written code from common
issues in graphical representation and maintenance, and utilises gesture-driven feedback as a channel for
enhanching software readability. An analysis of simple procedural and concurrent snippets of code using
the language and the conventions, core technical specifications and reasoning underlying key design choices
made in its conception were presented. Weve discussed the unavoidable architecture-specific issues in
platform-independent programming and described ways in which these can be alleviated using a software
structure that relies on as few platform-dependent mechanisms as possible, which we referred to as axioms.
We proposed that by providing developers with an interface to share platform-specific implementations of
functions that are comprised of compound calls to these axiomatic components, we may optimise performance
to the extent that approximates a native level of execution.
Though the tools and libraries developed in the project thus far exist in a very fundamental state, there
is no doubt in my mind concerning their applicability to the complex task of heterogeneous programming
that awaits just around the corner. The implementation of programmatic axioms to the generation of simple
boolean logic functions has served as only a taster of the rich functionality that draws ever nearer to our
grasp. The flexibility and modularity of the devised architecture has been applied to numerous unique
scenarios, and with each iteration it grew more powerful, more expressive, more robust. Its for this reason
that I have great confidence in the oncoming tangential leap into utilising these tools in an effort to achieve
truly platform-independent and language agnostic systems programming.

Novel Approaches to Programming Heterogeneous Computational Systems

23

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

Project Management
2015

07

08

09

2016

10

11

12

01

02

03

04

05

06

Total Duration
Application
Structure
Literature Review
Graphics Architecture
Interface Hierarchy Design
Events Management Pattern
Language Design
Literature Review
Lexicon Design
Lexicon Implementation
Hierarchical Distribution
Cascade Design
Language implemented!
Execution
Parsing
Procedural Simulation
Hello, world!
Invocation
Superseding
Concurrency

Figure 10 Project Gantt Chart (Depicts completion dates of outlined tasks).

Novel Approaches to Programming Heterogeneous Computational Systems

24

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

List of Figures
1
2
3
4
5
6
7
8
9

10

A child raised using tablet devices fruitlessly swipes at a magazine.[5] . . . . . . . . . . . . .


A maze solving algorithm written in Blockly; escape any maze by following the left hand side.
A procedural method in Punch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A punched card.[13] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A coupling nests a boolean literal which passes data into a contact on a nested coupling. . . .
An iteration contact accepts a boolean driver and sources an integer to the nested call. . . . .
Two concurrent processes have access to two shared variables defined by the surrounding
coupling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A graphical block in Punch may be superseded using conventional source languages. (Verilog)
(Left) A sequential execution path dependent on boolean input parameter. (Right) The sequential method expects an additional clock parameter within low level execution environments. This parameter, rendered using a void event type, lacks a driver and is therefore
starved of the input data. This in turn causes the diagram to be no longer synthesisable or
platform independent. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Project Gantt Chart (Depicts completion dates of outlined tasks). . . . . . . . . . . . . . . .

5
7
8
8
10
11
12
16

18
24

List of Tables
1
2
3

Truth table for the two-input N AN D. Binary drivers A and B result in output C. . . . . . .
Core procedural programmatic elements specification as of 2016. (Part A) . . . . . . . . . . .
Core procedural programmatic elements specification as of 2016. (Part B) . . . . . . . . . . .

Novel Approaches to Programming Heterogeneous Computational Systems

13
21
22

25

University of Manchester School of Electronic and Electrical Engineering

Alexander Thomas

References
[1] Computer Science - Research Councils UK, http://www.rcuk.ac.uk/skills/percase/computer/, 15
06 2016.
[2] TIOBE Index TIOBE - The Software Quality Company, http://www.tiobe.com/tiobe-index/, 15
06 2016.
[3] SwiftKey, https://swiftkey.com/en, 15 06 2016.
[4] Microsoft sets up AI push with SwiftKey deal - FT.com,
f86534c6-c9fa-11e5-be0b-b7ece4e953a0.html, 15 06 2016.

http://www.ft.com/cms/s/0/

[5] iPad
Baby
Cant
Work
a
ipad-baby-cant-work-a-magazine, 16 06 2016.

http://gawker.com/5849593/

Magazine,

[6] Scratch - Imagine, Program, Share, https://scratch.mit.edu/, 16 06 2016.


[7] Blockly - Google Developers, https://developers.google.com/blockly/, 16 06 2016.
[8] Single Frame - Scratch Wiki, https://wiki.scratch.mit.edu/wiki/Single_Frame, 28 06 2016.
[9] LabVIEW System Design Software - National Instruments, http://www.ni.com/labview/, 21 06 2016.
[10] Simulink - Simulation and Model-Based Design - Mathworks United Kingdom, http://uk.mathworks.
com/products/simulink/index.html?s_tid=gn_loc_drop, 21 06 2016.
[11] NoFlo Flow-Based Programming for JavaScript, http://noflojs.org/, 22 06 2016.
[12] Pure Data - Pd Community Site, https://puredata.info/, 22 06 2016.
[13] Holleriths Electric Tabulating Machine. Railroad Gazette. April 19, 1895. Retrieved 2016-06-23.
[14] Force
Directed
Graph
Algorithms,
force-directed.pdf, 23 06 2016.

https://cs.brown.edu/rt/gdhandbook/chapters/

[15] Carvalho, C. 2000. The gap between processor and memory speeds.. Departamento de Inform
atica,
Universidade do Minho 27.
[16] Yuh-Dauh, YD. 2006. De Morgans Laws. National Taiwan University. 135.
[17] Turing, A. 1950. Computing Machinery and Intelligence. 433-460.
[18] Chow, P. 1991. Reduced Instruction Set Computers. IEEE. 433-460.
[19] Hofstadter, D. 2007. I am a Strange Loop. Basic Books 138.
[20] Rohas, R. 1998. A Tutorial Introduction to the Lambda Calculus.
[21] Function pass by value vs . pass by reference, http://courses.washington.edu/css342/zander/
css332/passby.html, 12 07 2016.
[22] Altera Corporation. June 2014. Internal Memory (RAM and ROM) User Guide. 2-2:2-4.
[23] Hamblen, J and Furman, M. 2001. Rapid Prototyping of Digital Systems. 91:94.
[24] Chapter 6. The Java Virtual Machine Instruction Set, https://docs.oracle.com/javase/specs/
jvms/se7/html/jvms-6.html, 13 07 2016.

Novel Approaches to Programming Heterogeneous Computational Systems

26

Anda mungkin juga menyukai