
John T. O'DonnellUniversity of Glasgow | UofG · School of Computing Science
John T. O'Donnell
About
88
Publications
18,095
Reads
How we measure 'reads'
A 'read' is counted each time someone views a publication summary (such as the title, abstract, and list of authors), clicks on a figure, or views or downloads the full-text. Learn more
600
Citations
Introduction
Skills and Expertise
Publications
Publications (88)
Extensible sparse functional arrays (ESFA) is a persistent data structure with an implementation that performs every operation in O(1) time and space. There is no requirement for single threading of arrays, and no performance penalty for sharing. The implementation is an example of hardware/software co-design and also of active data structures. Thi...
Active data structures support operations that may affect a large number of elements of an aggregate data structure. They are well suited for extremely fine grain parallel systems, including circuit parallelism. General purpose GPUs were designed to support regular graphics algorithms, but their intermediate level of granularity makes them potentia...
A longstanding open question in algorithms and data structures is the time and space complexity of pure functional arrays. Imperative arrays provide update and lookup operations that require constant time in the RAM theoretical model, but it is conjectured that there does not exist a RAM algorithm that achieves the same complexity for functional ar...
A functional hardware description language enables students to gain a working
understanding of computer systems, and to see how the levels of abstraction fit
together. By simulating circuits, digital design becomes a living topic, like
programming, and not just a set of inert facts to memorise. Experiences gained
from more than 20 years of teaching...
Digital circuit simulation often requires a large amount of computation, resulting in long run times. We consider several techniques for optimising a brute force synchronous circuit simulator: an algorithm using an event queue that avoids recalculating quiescent parts of the circuit, a marking algorithm that is similar to the event queue but that a...
String players spend a significant amount of practice time creating and learning bowings. These may be indicated in the music using up-bow and down-bow symbols, but those traditional notations do not capture the complex bowing patterns that are latent within the music. Regular expressions, a mathematical notation for a simple class of formal langua...
This study considers a heterogeneous computing system and corresponding workload being investigated by the Extreme Scale Systems Center (ESSC) at Oak Ridge National Laboratory (ORNL). The ESSC is part of a collaborative effort between the Department ...
Playing a string instrument, such as the violin, requires solving many problems in controlling the bow. For example, the player may find that ‘saving bow’ is crucial to getting through a passage, yet not know why. Computer models may be able to help musicians to understand
such problems better and to find solutions. We have developed a simple bowin...
FPGAs make it practical to speed up a program by defining hardware functional units that perform calculations faster than can be achieved in software. Specialised digital circuits avoid the overhead of executing sequences of instructions, and they make available the massive parallelism of the components. The FPGA operates as a coprocessor controlle...
Digital circuits with feedback loops can solve some instances of NP-hard problems by relaxation: the circuit will either oscillate or settle down to a stable state that represents a solution to the problem instance. This approach differs from using hardware accelerators to speed up the execution of deterministic algorithms, as it exploits stabilisa...
Two ways to exploit chips with a very large number of transistors are multicore processors and programmable logic chips. Some data parallel algorithms can be executed efficiently on ordinary parallel computers, including multicores. A class of data parallel algorithms is identified which have characteristics that make implementation on multiprocess...
Hydra is a set of methods and software tools for carrying out digital circuit design using Haskell. It has been used successfully for three years in the third-year course on Computer Architecture at the University of Glasgow, with plans to extend its use to the advanced fourth-year course. Some of its innovative features are: Signal type classes; s...
Applicative (also called functional) programming systems prohibit side effects, including assignments to variables. This restriction has several advantages, including referential transparency and potential parallel program execution. A major disadvantage, however, is that aggregate data structures become very expensive to maintain: when the program...
A haptic model of bowing the violin and viola is presented that focuses on just the geometry of the contact point between the bow hair and the string, giving a simplified description that focuses on aspects which the performer thinks about consciously. The model allows artificial constraints on the bow motion to be provided, giving the player physi...
A set of communication operations is defined, which allows a form of task parallelism to be achieved in a data parallel architecture. The set of processors can be subdivided recursively into groups, and a communication operation inside a group never conflicts with communications taking place in other groups. The groups may be subdivided and recombi...
Using Haskell as a digital circuit description language, we transform a ripple carry adder that requires $O(n)$ time to add two $n$-bit words into a parallel carry lookahead adder that requires $O(\log n)$ time. The ripple carry adder uses a scan function to calculate carry bits, but this scan cannot be parallelized directly since it is applied to...
Summary form only given. The simultaneous exploitation of task and data parallelism is often beneficial for the execution of computation-intensive applications on large parallel machines with a distributed address space, since the concurrent execution of independent program parts may significantly reduce the communication overhead. This article out...
A wide range of domain-specific languages (DSLs) has been implemented successfully by embedding them in general purpose lan- guages. This paper reviews embedding, and summarizes how two alter- native techniques—staged interpreters and templates—can be used to overcome the limitations of embedding. Both techniques involve a form of generative progra...
Hydra is a domain-specic language for designing digital cir- cuits, which is implemented by embedding within Haskell. Many features required for hardware specication t well within functional languages, leading in many cases to a perfect embedding. There are some situa- tions, including netlist generation and software logic probes, where the DSL doe...
Hydra is a computer hardware description language that integrates several kinds of software tool (simulation, netlist generation and timing analysis) within a single circuit specication. The design language is in- herently concurrent, and it oers black box abstraction and general design patterns that simplify the design of circuits with regular str...
Formal program transformation in a functional language can be used to support incremental design of parallel programs. This paper illustrates the method with a detailed example: a program transformation that improves the static load balance of a simple data parallel program.
The Abstract Parallel Machine (APM) model separates the definitions of parallel operations from the application algorithm,
which defines the sequence of parallel operations to be executed. An APM contains a set of parallel operation definitions,
which specify how the computation is organized into independent sites of computation and what data excha...
Any parallel programming language provides a model of parallelism, which is accepted implicitly when programming directly in the language. We propose a more flexible approach to models of parallelism: in our methodology, the program is derived in a sequence of steps, where the algorithm version in each step incorporates just one decision and is bas...
Introduction to Haskell * Propositional Logic * Predicate Logic * Set Theory * Recursion * Inductively Defined Sets * Induction * Relations * Functions * Digital Circuit Design * Appendix A: Software Tools for Discrete Mathematics * Appendix B: Resources on the Web * Appendix C: Solutions to Selected Exercises * Bibliography * Index.
The implementation of irregular algorithms with dynamic access patterns often requires the use of complex data structures and makes essential use of side effects. An example is the hierarchical radiosity method, a global illumination method from computer graphics, which uses dynamically growing trees with mutual interactions. The irregularity of th...
SPMD programs are usually written from the perspective of a single processor, yet the intended behaviour is an aggregate computation
comprising many processors running the same program on local data. Combinators, suchas map, fold, scan and multibroadcast,
provide a flexible way to express SPMD programs more naturally and more abstractly at the coll...
A function is an abstract model of computation: you give it some input, and it produces a result. The essential aspect is that the result is completely determined by the input: if you repeatedly apply the same function to the same argument, you will always obtain the same result. Examples of functions include:
An inquiry to a telephone directory se...
The techniques of discrete mathematics which you have been studying in this book are used throughout computer science. So far we have seen many small examples of the application of mathematics to computing, and we have also used programming to help with the mathematics.
It is frequently necessary to reason logically about statements of the form everything has the property p or something has the property p. One of the oldest and most famous pieces of logical reasoning, which was known to the ancient Greeks, is an example:
All men are mortal. Socrates is a man. Therefore Socrates is mortal.
A common type of problem is to prove that an object x has some property P. The mathematical notation for this is P (x), where P stands for predicate (or property). For example, if x is 6 and P (x) is the predicate ‘x is an even number’, then we could express the statement ‘6 is an even number’ with the shorthand mathematical statement P(6).
Logic provides a powerful tool for reasoning correctly about mathematics, algorithms and computers. It is used extensively throughout computer science, and you need to understand its basic concepts in order to study many of the more advanced subjects in computing. Here are just a few examples, spanning the entire range of computing applications, fr...
The topic of this book is discrete mathematics with an emphasis on its connections with computers:
The computer can help you to learn and understand mathematics. As various mathematical objects are defined, software tools will enable you to perform calculations with those objects. Exploring and experimenting with mathematical ideas gives a practica...
Set theory is one of the most fundamental branches of mathematics. Many profound advances in mathematics over the last century have taken place in set theory, and there is a deep connection between set theory and logic. More importantly for computer science, it has turned out that the notation and terminology of elementary set theory is extremely u...
In this chapter, we explore the construction of sets using induction. To understand why induction is useful, consider the problem of defining a set. The simplest method is to define a set by naming each of its elements, one by one. This is called enumeration. It works only for finite sets and is impractical for large sets. Another approach is to us...
Recursion is a self referential style of definition commonly used in both mathematics and computer science. It is a fundamental programming tool, particularly important for manipulating data structures.
There are many kinds of relationship that occur in everyday life. Some of these describe how the members of a family are related to each other: parent, child, brother, sister, sibling. We could also have a relation called is in for cities and countries: for example, London is in Great Britain, and Paris is in France. Or we could have a relation tha...
The idea behind data parallel programming is to perform global operations over large data structures, where the individual operations on singleton elements of the data structure are performed simultaneously. In the simplest case, for example, this means that a loop over an array is replaced by a constant-time aggregate operation. In order to introd...
this paper develops such a scheme, called "hardware description with recursion equations" (abbreviated HDRE and pronounced as hydra). A designer using HDRE may describe a circuit using a simple set of primitive functions written in an underlying general purpose programming language, and the description itself is just a function written in that lang...
It is easy to write a circuit specification in a pure functional language so that execution of the specification simulates the circuit. It's harder to make an executable specification generate the circuit's netlist without using impure language features. The difficulty is that a circuit specification evaluates to a graph isomorphic to the circuit,...
. This paper addresses the problem of using functional programming on a SIMD or data parallel architecture. Each type of operation the architecture can perform corresponds to a particular function application. Therefore it is possible to write low level data parallel algorithms directly in a functional language. This has two advantages: the low lev...
Any parallel programrning language provides a model of parallelism, and one can write a program directly in the language, accepting the fixed given model. We propose an alternative methodology: the program is derived in a sequence of steps, where each step incorporates just one decision, and is based on a specific model of parallelism, called an ab...
Interconnection networks are an important and well-studied topic in parallel computing and architecture, but a homogeneous and general method for defining and classifying the topologies and behaviors of interconnection networks is lacking. Topologies are usually specified informally by picture or more formally by permutations of wire enumerations....
The parallel scan algorithm plays an important role in parallel programming, but previous explanations of it generally rely on informal methods that fail to establish its correctness. Equational reasoning in a pure functional language provides a formal vehicle for stating the parallel scan algorithm and proving that a parallel architecture executes...
Bidirectional fold generalises foldl and foldr to allow simultaneous communication in both directions across a list. Bidirectional scan calculates the list of partial results of a bidirectional fold, just as scanl and scanr calculate the partial results of a foldl or foldr. Mapping scans combine a map with a scan, and often simplify programs using...
The Functional Programming Group at the University of Glasgow was started in 1986 by John Hughes and Mary Sheeran. Since then it has grown in size and strength, becoming one of the largest computing science research groups at Glasgow and earning an international reputation. The first Glasgow Functional Programming Workshop was organised in the summ...
Three important generalised array structures — extensible arrays, sparse arrays and functional arrays — are slow to access unless their use is severely restricted. All three can be combined in a powerful new active data structure called 'ESF arrays'. ESF arrays may grow or shrink dynamically, they can be searched quickly, and changes to them can be...
Nondeterminism can be introduced into a functional language, along with a set of laws for reasoning about the behaviour of programs, without disturbing referential transparency. We show how to do this by adding a new type constructor for sets and a carefully selected family of operations on sets. Instead of specifying a nondeterministic choice expl...
This paper considers the problems of debugging large programs written in a pure functional style by experienced functional programmers. Several levels of debugging support are defined: specification, algorithmic, semantic, architectural and machine. We focus on the provision of tools for supporting algorithmic and semantic debugging. A significant...
For some time functional language researchers have experimented with non-deterministic constructs for these otherwise deterministic languages. One strong motivation to do so is the desire to express necessarily non-deterministic programs, such as operating systems and interactive systems that service requests from several terminals in the order in...
A method of implementing declarative data structures efficiently
on a data parallel architecture is illustrated by the implementation of
a data parallel algorithm for functional arrays on the massively
parallel processor (MPP). Functional arrays are defined, and it is shown
why the basic operations on them are slow when implemented on a
sequential...
The Applicative Programming System Architecture contains a novel Data Structure Memory (DSM) which supports fast access operations on compact linear data structures. Several problems that arise in implementations of applicative and functional programming languages can be solved efficiently using special data representations on the DSM. Each memory...
Applicative programming languages have several properties that appear to make debugging difficult. First, the absence of assignment statements complicates the notion of changing a program while debugging. Second, the absence of imperative input and output makes it harder to obtain information about what the program is doing. Third, the presence of...
The components of a programming environment must communicate with the user while maintaining a state that is constantly evolving. We introduce the “dialogue”, an abstraction of such components, and we implement a dialogue function in a purely applicative language. The dialogue function exploits the properties of lasy evaluation and recursion to imp...
Lisp and its successors provide the programmer with a powerful single tool [2] in which he can write, modify, debug and execute programs. Side effects play a crucial role in these programming environments. We propose an alternative approach to debugging that doesn't rely on side effects. Then we describe an implementation of our approach in a purel...
Lisp and its successors provide the programmer with a powerful single tool [2] in which he can write, modify, debug and execute programs. Side effects play a crucial role in these programming environments. We propose an alternative approach to debugging that doesn't rely on side effects. Then we describe an implementation of our approach in a purel...
A wide range of domain-specific languages (DSLs) has been implemented successfully by embedding them in general purpose lan- guages. This paper reviews embedding, and summarizes how two alter- native techniques—staged interpreters and templates—can be used to overcome the limitations of embedding. Both techniques involve a form of generative progra...
Using Haskell as a digital circuit description language, we transform a ripple carry adder that requires O(n) time to add two n-bit words into an ecient carry looka- head adder that requires O(logn) time. The gain in speed relies on the use of parallel scan to calculate the propagation of carry bits eciently. The main diculty is that this scan cann...
An attractive way to implement domain specific languages (DSLs) is by writing a library in a host language. Some DSLs, however, do not fit perfectly within the host language and a pure library solu-tion is insufficient. In many cases, metaprogramming offers a solution to the problem. This paper surveys and compares the metaprogram-ming support offe...
Thesis (Ph.D.)--University of Iowa, 1981. Includes bibliographical references (p. 259-261). Photocopy of typescript.