Programmable Microfluidics Bill Thies Computer Science and Artificial Intelligence Laboratory Massachusetts Institute of Technology UC Berkeley – October.

Slides:



Advertisements
Similar presentations
System Integration and Performance
Advertisements

FPGA (Field Programmable Gate Array)
Computer Abstractions and Technology
The Assembly Language Level
Introduction to Computer Programming Nai-Wei Lin Department of Computer Science and Information Engineering National Chung Cheng University.
Computer-Aided Design for Microfluidic Chips Based on Multilayer Soft Lithography Nada Amin 1, William Thies 2, Saman Amarasinghe 1 1 Massachusetts Institute.
1 HW/SW Partitioning Embedded Systems Design. 2 Hardware/Software Codesign “Exploration of the system design space formed by combinations of hardware.
Monolithic Microfabricated Valves and Pumps by Multilayer Soft Lithography EECE 491C Unger et al. (Quake group, CALTECH) Science, 2000.
CS244-Introduction to Embedded Systems and Ubiquitous Computing Instructor: Eli Bozorgzadeh Computer Science Department UC Irvine Winter 2010.
Microfluidic Biochips: Design, Programming, and Optimization Bill Thies Joint work with Vaishnavi Ananthanarayanan, J.P. Urbanski, Nada Amin, David.
Chapter 2: Impact of Machine Architectures What is the Relationship Between Programs, Programming Languages, and Computers.
Testing an individual module
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 1: An Overview of Computers and Programming Languages C++ Programming:
1 ES 314 Advanced Programming Lec 2 Sept 3 Goals: Complete the discussion of problem Review of C++ Object-oriented design Arrays and pointers.
Basic Computer Organization CH-4 Richard Gomez 6/14/01 Computer Science Quote: John Von Neumann If people do not believe that mathematics is simple, it.
Chapter 6 Memory and Programmable Logic Devices
Operating Systems Concepts 1. A Computer Model An operating system has to deal with the fact that a computer is made up of a CPU, random access memory.
 A data processing system is a combination of machines and people that for a set of inputs produces a defined set of outputs. The inputs and outputs.
Tabu Search-Based Synthesis of Dynamically Reconfigurable Digital Microfluidic Biochips Elena Maftei, Paul Pop, Jan Madsen Technical University of Denmark.
Language Evaluation Criteria
Chapter 1 CSF 2009 Computer Abstractions and Technology.
Bringing Programmability to Experimental Biology Bill Thies Joint work with Vaishnavi Ananthanarayanan, J.P. Urbanski, Nada Amin, David Craig, Jeremy Gunawardena,
Development in hardware – Why? Option: array of custom processing nodes Step 1: analyze the application and extract the component tasks Step 2: design.
An Introduction Chapter Chapter 1 Introduction2 Computer Systems  Programmable machines  Hardware + Software (program) HardwareProgram.
Programmable Microfluidics Using Soft Lithography J.P. Urbanski Advisor: Todd Thorsen Hatsopoulos Microfluidics Lab, MIT January 25/2006.
1 Computing Software. Programming Style Programs that are not documented internally, while they may do what is requested, can be difficult to understand.
EET 4250: Chapter 1 Computer Abstractions and Technology Acknowledgements: Some slides and lecture notes for this course adapted from Prof. Mary Jane Irwin.
Sogang University Advanced Computing System Chap 1. Computer Architecture Hyuk-Jun Lee, PhD Dept. of Computer Science and Engineering Sogang University.
CS/ECE 3330 Computer Architecture Kim Hazelwood Fall 2009.
The Beauty and Joy of Computing Lecture #3 : Creativity & Abstraction UC Berkeley EECS Lecturer Gerald Friedland.
Chapter 1 Introduction to Computers and C++ Programming Goals: To introduce the fundamental hardware and software components of a computer system To introduce.
Programmable Microfluidics William Thies*, J.P. Urbanski †, Mats Cooper †, David Wentzlaff*, Todd Thorsen †, and Saman Amarasinghe * * Computer Science.
COE 405 Design and Modeling of Digital Systems
1 Towards Optimal Custom Instruction Processors Wayne Luk Kubilay Atasu, Rob Dimond and Oskar Mencer Department of Computing Imperial College London HOT.
Computer Organization and Design Computer Abstractions and Technology
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 1: An Overview of Computers and Programming Languages.
1 International Technology University CEN 951 Computer Architecture Lecture 1 - Introduction.
CS244-Introduction to Embedded Systems and Ubiquitous Computing Instructor: Eli Bozorgzadeh Computer Science Department UC Irvine Winter 2010.
I Robot.
Computer Architecture And Organization UNIT-II General System Architecture.
Chapter 1 Computer Abstractions and Technology. Chapter 1 — Computer Abstractions and Technology — 2 The Computer Revolution Progress in computer technology.
1 Text Reference: Warford. 2 Computer Architecture: The design of those aspects of a computer which are visible to the programmer. Architecture Organization.
CHAPTER 8 Developing Hard Macros The topics are: Overview Hard macro design issues Hard macro design process Physical design for hard macros Block integration.
CS 127 Introduction to Computer Science. What is a computer?  “A machine that stores and manipulates information under the control of a changeable program”
Data Structures and Algorithms Dr. Tehseen Zia Assistant Professor Dept. Computer Science and IT University of Sargodha Lecture 1.
Electronic Analog Computer Dr. Amin Danial Asham by.
A System to Generate Test Data and Symbolically Execute Programs Lori A. Clarke Presented by: Xia Cheng.
1 of 16 April 25, 2006 System-Level Modeling and Synthesis Techniques for Flow-Based Microfluidic Large-Scale Integration Biochips Contact: Wajid Hassan.
Abstraction Layers for Scalable Microfluidic Biocomputers William Thies*, J.P. Urbanski †, Todd Thorsen † and Saman Amarasinghe * * Computer Science and.
Towards Programmable Microfluidics William Thies
Digital Computer Concept and Practice Copyright ©2012 by Jaejin Lee Control Unit.
Wajid Minhass, Paul Pop, Jan Madsen Technical University of Denmark
DR. SIMING LIU SPRING 2016 COMPUTER SCIENCE AND ENGINEERING UNIVERSITY OF NEVADA, RENO Session 2 Computer Organization.
COMPUTER ARCHITECTURE & OPERATIONS I Instructor: Yaohang Li.
Onlinedeeneislam.blogspot.com1 Design and Analysis of Algorithms Slide # 1 Download From
An Exact Algorithm for Difficult Detailed Routing Problems Kolja Sulimma Wolfgang Kunz J. W.-Goethe Universität Frankfurt.
Progression in KS3/4 Algorithms MONDAY 30 TH NOVEMBER SUE SENTANCE.
Review A program is… a set of instructions that tell a computer what to do. Programs can also be called… software. Hardware refers to… the physical components.
1 Chapter 1 Background Fundamentals of Java: AP Computer Science Essentials, 4th Edition Lambert / Osborne.
1 The user’s view  A user is a person employing the computer to do useful work  Examples of useful work include spreadsheets word processing developing.
Wolfgang Runte Slide University of Osnabrueck, Software Engineering Research Group Wolfgang Runte Software Engineering Research Group Institute.
Support for Program Analysis as a First-Class Design Constraint in Legion Michael Bauer 02/22/17.
COMPUTER ORGANIZATION & ASSEMBLY LANGUAGE
Paper Microfluidic Devices
Elena Maftei Technical University of Denmark DTU Informatics
Chapter 1: An Overview of Computers and Programming Languages
C++ Programming: From Problem Analysis to Program Design
Programmable Microfluidics Bill Thies Joint work with J. P
Microfluidic Biochips
HIGH LEVEL SYNTHESIS.
Presentation transcript:

Programmable Microfluidics Bill Thies Computer Science and Artificial Intelligence Laboratory Massachusetts Institute of Technology UC Berkeley – October 25, 2007

Acknowledgements Prof. Todd Thorsen J.P. Urbanski David Craig MIT Hatsopoulos Microfluids Laboratory Prof. Jeremy Gunawardena Natalie Andrew Prof. Mark Johnson David Potter Colorado Center for Reproductive Medicine Prof. Saman Amarasinghe Nada Amin MIT Computer Science and Artificial Intelligence Laboratory Harvard Medical School

Microfluidic Chips Idea: a whole biology lab on a single chip –Input/output –Sensors: pH, glucose, temperature, etc. –Actuators: mixing, PCR, electrophoresis, cell lysis, etc. Benefits: –Small sample volumes –High throughput –Geometrical manipulation Applications: –Biochemistry - Cell biology –Biological computing [Farfel/Stefanovic] [Grover/Mathies] [Gehani/Reif] [Livstone/Landweber][van Noort][McCaskill] [Somei/Kaneda/Fujii/Murata] 1 mm 10x real-time

Moore’s Law of Microfluidics: Valve Density Doubles Every 4 Months Source: Fluidigm Corporation (

Moore’s Law of Microfluidics: Valve Density Doubles Every 4 Months Source: Fluidigm Corporation (

Current Practice: Expose Gate-Level Details to Users Manually map experiment to the valves of the device –Using Labview or custom C interface –Given a new device, start over and do mapping again

Our Approach: “Write Once, Run Anywhere” Example: Gradient generation Hidden from programmer: –Location of fluids –Details of mixing, I/O –Logic of valve control –Timing of chip operations 450 Valve Operations Fluid yellow = input (0); Fluid blue = input(1); for (int i=0; i<=4; i++) { mix(yellow, 1-i/4, blue, i/4); }

Example: Gradient generation Hidden from programmer: –Location of fluids –Details of mixing, I/O –Logic of valve control –Timing of chip operations setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); 450 Valve Operations Fluid yellow = input (0); Fluid blue = input(1); for (int i=0; i<=4; i++) { mix(yellow, 1-i/4, blue, i/4); } Our Approach: “Write Once, Run Anywhere”

450 Valve Operations Example: Gradient generation Hidden from programmer: –Location of fluids –Details of mixing, I/O –Logic of valve control –Timing of chip operations setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); Fluid yellow = input (0); Fluid blue = input(1); for (int i=0; i<=4; i++) { mix(yellow, 1-i/4, blue, i/4); } Our Approach: “Write Once, Run Anywhere”

Fluidic Abstraction Layers Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing Protocol Description Language - readable code with high-level mixing ops Fluidic Hardware Primitives - valves, multiplexers, mixers, latches chip 1chip 2chip 3 C x86 Pentium III, Pentium IV Silicon Analog transistors, registers, …

Fluidic Abstraction Layers Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing Protocol Description Language - readable code with high-level mixing ops chip 1chip 2chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches Benefits: –Division of labor –Portability –Scalability –Expressivity

Fluidic Abstraction Layers Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing Protocol Description Language - readable code with high-level mixing ops chip 1chip 2chip 3 Fluidic Hardware Primitives - valves, multiplexers, mixers, latches Benefits: –Division of labor –Portability –Scalability –Expressivity

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 0. Start with mask of channels

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 1. Deposit pattern on silicon wafer

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 2. Pour PDMS over mold - polydimexylsiloxane: “soft lithography” Thick layer (poured) Thin layer (spin-coated)

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 3. Bake at 80° C (primary cure), then release PDMS from mold

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 4a. Punch hole in control channel 4b. Attach flow layer to glass slide

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 5. Align flow layer over control layer

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer 6. Bake at 80° C (secondary cure)

Primitive 1: A Valve (Quake et al.) Control Layer Flow Layer pressure actuator 7. When pressure is high, control channel pinches flow channel to form a valve

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2Bit 1Bit Input Output 0 Output 7 Output 6 Output 5 Output 4 Output 3 Output 2 Output 1 flow layer control layer

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2Bit 1Bit Input Output 0 Output 7 Output 6 Output 5 Output 4 Output 3 Output 2 Output 1 Example: select 3 = 011 flow layer control layer

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2Bit 1Bit Input Output 0 Output 7 Output 6 Output 5 Output 4 Output 3 Output 2 Output 1 Example: select 3 = 011 flow layer control layer

Primitive 2: A Multiplexer (Thorsen et al.) Bit 2Bit 1Bit Input Output 0 Output 7 Output 6 Output 5 Output 4 Output 3 Output 2 Output 1 Example: select 3 = 011 flow layer control layer

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top 2. Load sample on bottom

Primitive 3: A Mixer (Quake et al.) 1. Load sample on top 2. Load sample on bottom 3. Peristaltic pumping Rotary Mixing

Primitive 4: A Latch (Our contribution) Purpose: align sample with specific location on device –Examples: end of storage cell, end of mixer, middle of sensor Latches are implemented as a partially closed valve –Background flow passes freely –Aqueous samples are caught Sample Latch

Primitive 5: Cell Trap Several methods for confining cells in microfluidic chips –U-shaped weirs- C-shaped rings / microseives –Holographic optical traps- Dialectrophoresis In our chips: U-Shaped Microseives in PDMS Chambers Source: Wang, Kim, Marquez, and Thorsen, Lab on a Chip 2007

Primitive 6: Imaging and Detection As PDMS chips are translucent, contents can be imaged directly –Fluorescence, color, opacity, etc. Feedback can be used to drive the experiment

Fluidic Abstraction Layers Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing Protocol Description Language - readable code with high-level mixing ops Fluidic Hardware Primitives - valves, multiplexers, mixers, latches chip 1chip 2chip 3

Toward “General Purpose” Microfluidic Chips

Abstraction 1: Digital Architecture Recent techniques can control independent samples –Droplet-based samples –Continuous-flow samples –Microfluidic latches In abstract machine, all samples have unit volume –Input/output a sample –Store a sample –Operate on a sample Challenge for a digital architecture: fluid loss –No chip is perfect – will lose some volume over time –Causes: imprecise valves, adhesion to channels, evaporation,... –How to maintain digital abstraction? [Fair et al.] [Our contribution]

Maintaining a Digital Abstraction Instruction Set Architecture (ISA) High-Level Language Hardware Electronics Microfluidics Replenish charge (GAIN) Loss of charge Randomized Gates [Palem] Soft error Handling? Replenish fluids? - Maybe (e.g., with water) - But may affect chemistry Loss of fluids ? ? ? ? ? ? Expose loss in ISA - Compiler deals with it Expose loss in language - User deals with it

Abstraction 2: Mix Instruction Microfluidic chips have various mixing technologies –Electrokinetic mixing –Droplet mixing –Rotary mixing Common attributes: –Ability to mix two samples in equal proportions, store result Fluidic ISA: mix (int src 1, int src 2, int dst) –Ex: mix(1, 2, 3) –To allow for lossy transport, only 1 unit of mixture retained [Quake et al.] [Fair et al.] [Levitan et al.] Storage Cells Mixer

Gradient Generation in Fluidic ISA

setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); Gradient Generation in Fluidic ISA input(0, 0); input(1, 1); input(0, 2); mix(1, 2, 3); input(0, 2); mix(2, 3, 1); input(1, 3); input(0, 4); mix(3, 4, 2); input(1, 3); input(0, 4); mix(3, 4, 5); input(1, 4); mix(4, 5, 3); mix(0, 4); Direct Control valve actuations - only works on 1 chip Fluidic ISA - 15 instructions - portable across chips abstraction setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW); setValve(0, HIGH); setValve(1, HIGH); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, LOW); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, LOW); setValve(11, HIGH); setValve(12, LOW); setValve(13, HIGH); setValve(14, LOW); setValve(15, HIGH); setValve(16, LOW); setValve(17, LOW); setValve(18, LOW); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(14, HIGH); setValve(2, LOW); wait(1000); setValve(4, HIGH); setValve(12, LOW); setValve(16, HIGH); setValve(18, HIGH); setValve(19, LOW); wait(2000); setValve(0, LOW); setValve(1, LOW); setValve(2, LOW); setValve(3, HIGH); setValve(4, LOW); setValve(5, HIGH); setValve(6, HIGH); setValve(7, LOW); setValve(8, LOW); setValve(9, HIGH); setValve(10, HIGH); setValve(11, LOW); setValve(12, LOW); setValve(13, LOW); setValve(14, LOW); setValve(15, HIGH); setValve(16, HIGH); setValve(17, LOW); setValve(18, HIGH); setValve(19, LOW);

Implementation: Oil-Driven Chip InputsStorage CellsBackground PhaseWash PhaseMixing Chip 128Oil—Rotary

Implementation: Oil-Driven Chip InputsStorage CellsBackground PhaseWash PhaseMixing Chip 128Oil—Rotary mix (S 1, S 2, D) { 1. Load S 1 2. Load S 2 3. Rotary mixing 4. Store into D } 50x real-time

Implementation 2: Air-Driven Chip InputsStorage CellsBackground PhaseWash PhaseMixing Chip 128Oil—Rotary Chip 2432AirWaterIn channels

Implementation 2: Air-Driven Chip mix (S 1, S 2, D) { 1. Load S 1 2. Load S 2 3. Mix / Store into D 4. Wash S 1 5. Wash S 2 } InputsStorage CellsBackground PhaseWash PhaseMixing Chip 128Oil—Rotary Chip 2432AirWaterIn channels 50x real-time

Fluidic Abstraction Layers Fluidic Instruction Set Architecture (ISA) - primitives for I/O, storage, transport, mixing Protocol Description Language - readable code with high-level mixing ops Fluidic Hardware Primitives - valves, multiplexers, mixers, latches chip 1chip 2chip 3

Fluid[] out = new Fluid[8]; Fluid yellow, blue, green; out[0] = input(0); yellow = input(0); blue = input(1); green = mix(yellow, blue); yellow = input(0); out[1] = mix(yellow, green); yellow = input(0); blue = input(1); out[2] = mix(yellow, blue); yellow = input(0); blue = input(1); green = mix(yellow, blue); blue = input(1); out[3] = mix(blue, green); out[4] = input(1); Abstraction 1: Managing Fluid Storage Programmer uses location-independent Fluid variables –Runtime system assigns & tracks location of each Fluid –Comparable to automatic memory management (e.g., Java) Fluidic ISA 1. Storage Management input(0, 0); input(1, 1); input(0, 2); mix(1, 2, 3); input(0, 2); mix(2, 3, 1); input(1, 3); input(0, 4); mix(3, 4, 2); input(1, 3); input(0, 4); mix(3, 4, 5); input(1, 4); mix(4, 5, 3); mix(0, 4);

Fluid[] out = new Fluid[8]; Fluid yellow, blue, green; out[0] = input(0); yellow = input(0); blue = input(1); green = mix(yellow, blue); yellow = input(0); out[1] = mix(yellow, green); yellow = input(0); blue = input(1); out[2] = mix(yellow, blue); yellow = input(0); blue = input(1); green = mix(yellow, blue); blue = input(1); out[3] = mix(blue, green); out[4] = input(1);

Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; Fluid[] out = new Fluid[8]; Fluid yellow, blue, green; out[0] = input(0); yellow = input(0); blue = input(1); green = mix(yellow, blue); yellow = input(0); out[1] = mix(yellow, green); yellow = input(0); blue = input(1); out[2] = mix(yellow, blue); yellow = input(0); blue = input(1); green = mix(yellow, blue); blue = input(1); out[3] = mix(blue, green); out[4] = input(1); Abstraction 2: Fluid Re-Generation 2. Fluid Re-Generation Programmer may use a Fluid variable multiple times –Each time, a physical Fluid is consumed on-chip –Runtime system re-generates Fluids from computation history

Custom Re-Generation Some species cannot be regenerated by repeating history –e.g., if selective mutagenesis has evolved unique sequence Users can extend Fluid class, specify how to regenerate –e.g., run PCR to amplify sequence of interest class DNASample extends Fluid { // Return array of fluids that are equivalent to this fluid Fluid[] regenerate() { Fluid amplified = performPCR(this, cycles, primer1, primer2, …); Fluid[] diluted = dilute(amplified, Math.pow(2, cycles)); return diluted; } // Return minimum quantity of this fluid needed to generate others int minQuantity() { return 1; } }

Unique Fluids Prohibit Re-Generation Some Fluids may be unique, with no way to amplify –E.g., products of cell lysis Users can express this constraint using a UniqueFluid: Can compiler verify that unique fluids used only once? –Unique (linear) types is a rich research area in prog. languages [Wadler] [Hogg] [Baker] [Minsky] [Boyland] [Fahndrich & DeLine] –But solutions often require annotations & do not handle arrays –Practical approach: verify in simple cases, warn about others  Opportunity for programming language research class UniqueFluid extends Fluid { Fluid[] regenerate() { throw new EmptyFluidException(); } } UniqueFluid f = lysisProduct(); UniqueFluid[] diluted = dilute(f); for (int i=0; i<diluted.length; i++) { analyze(diluted[i]); }

Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; 2. Fluid Re-Generation

Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; 2. Fluid Re-Generation

Abstraction 3: Arbitrary Mixing Allows mixing fluids in any proportion, not just 50/50 –Fluid mix (Fluid F 1, float p 1, Fluid f 2, float F 2 )  Returns Fluid that is p 1 parts F 1 and p 2 parts F 2 –Runtime system translates to 50/50 mixes in Fluidic ISA –Note: some mixtures only reachable within error tolerance  Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); out[0] = yellow; out[1] = mix(yellow, 3/4, blue, 1/4); out[2] = mix(yellow, 1/2, blue, 1/2); out[3] = mix(yellow, 1/4, blue, 3/4); out[4] = blue; 3. Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; 2. Fluid Re-Generation

Abstraction 3: Arbitrary Mixing Allows mixing fluids in any proportion, not just 50/50 –Fluid mix (Fluid F 1, float p 1, Fluid f 2, float F 2 )  Returns Fluid that is p 1 parts F 1 and p 2 parts F 2 –Runtime system translates to 50/50 mixes in Fluidic ISA –Note: some mixtures only reachable within error tolerance  Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); out[0] = yellow; out[1] = mix(yellow, 3/4, blue, 1/4); out[2] = mix(yellow, 1/2, blue, 1/2); out[3] = mix(yellow, 1/4, blue, 3/4); out[4] = blue; 3. Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input(0); Fluid blue = input(1); Fluid green = mix(yellow, blue); out[0] = yellow; out[1] = mix(yellow, green); out[2] = green; out[3] = mix(blue, green); out[4] = blue; 2. Fluid Re-Generation

Abstraction 3: Arbitrary Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); for (int i=0; i<=4; i++) { out[i] = mix(yellow, 1-i/4, blue, i/4); } Allows mixing fluids in any proportion, not just 50/50 –Fluid mix (Fluid F 1, float p 1, Fluid f 2, float F 2 )  Returns Fluid that is p 1 parts F 1 and p 2 parts F 2 –Runtime system translates to 50/50 mixes in Fluidic ISA –Note: some mixtures only reachable within error tolerance  4. Parameterized Mixing Fluid[] out = new Fluid[8]; Fluid yellow = input (0); Fluid blue = input (1); out[0] = yellow; out[1] = mix(yellow, 3/4, blue, 1/4); out[2] = mix(yellow, 1/2, blue, 1/2); out[3] = mix(yellow, 1/4, blue, 3/4); out[4] = blue; 3. Arbitrary Mixing

Abstraction 4: Cell Traps Unlike fluids, cells adhere to a specific location on chip –To interact with cells, need to move Fluids to their location CellTrap abstraction establishes a fixed chamber on chip –Fundamental capability: fill with a given fluid (incl. cell culture)

Abstraction 4: Cell Traps Unlike fluids, cells adhere to a specific location on chip –To interact with cells, need to move Fluids to their location CellTrap abstraction establishes a fixed chamber on chip –Fundamental capability: fill with a given fluid (incl. cell culture) class CellTrap { // establish a new, empty location on chip CellTrap(); // replace contents of cell trap with new fluid; return old contents UniqueFluid drainAndRefill(Fluid newContents); // regenerate contents of cell trap; return drained fluid as needed Fluid drainAndRegenerate(); }

Abstraction 4: Cell Traps CellTrap celltrap = new CellTrap(); // setup cell culture for (int i=0; i<N; i++) celltrap.drainAndRefill(cellCulture); celltrap.drainAndRefill(distilledWater); // analyze cell metabolites Fluid metabolites = drainAndRegenerate(); analyzeWithIndicators(metabolites); celltrap.drainAndRefill(antibodyStain); // stain cells for imaging  Must schedule all uses of metabolites before staining –Otherwise, runtime error –Like unique variables, difficult to verify safety in general case –But thanks to language, compiler can give useful warnings

Abstraction 5: Timing Constraints Precise timing is critical for many biology protocols –Minimum delay: cell growth, enzyme digest, denaturing, etc. –Maximum delay: avoid precipitation, photobleaching, etc. –Exact delay: regular measurements, synchronized steps, etc. Simple API for indicating timing constraints: –fluid.useBetween(N, M) – celltrap.useBetween(N, M)  Schedule next use of a Fluid(or drain of a CellTrap) between N and M seconds from time of the call  Also becomes part of Fluid’s regeneration history Note: may require parallel execution –Fluid f1 = mix(…); f1.useBetween(10, 10); –Fluid f2 = mix(…); f2.useBetween(10, 10); –Fluid f3 = mix(f1, f2); f1f1 f2f2 f3f3 10

Scheduling the Execution Scheduling problem has two parts: 1.Given dependence graph, find a good schedule 2.Extract dependence graph from the program

1. Finding a Schedule Abstract scheduling problem: –Given task graph G = (V, E) with [min, max] latency per edge –Find shortest schedule (V  Z) respecting latency on each edge  Case 1: Unbounded parallelism Can express as system of linear difference constraints Solve optimally in polynomial time  Case 2: Limited parallelism Adds constraint: only k vertices can be scheduled at once Can be shown to be NP-hard (reduce from PARTITION) Rely on greedy heuristics for now

2. Extracting Dependence Graph Static analysis difficult due to aliasing, etc. –Requires extracting precise producer-consumer relationships Opportunity: Perform scheduling at runtime, using lazy evaluation –Microfluidic operations are slow  computer can run ahead –Build dependence graph of all operations up to decision point Hazard: constraints that span decision points –Dynamic analysis cannot look into upcoming control flow –We currently prohibit such constraints – leave as open problem

BioStream Protocol Language Implements the abstractions –Full support for storage management, fluid re-generation, arbitrary mixing –Partial support for cells, timing Implemented as a Java library –Allows flexible integration with general-purpose Java code Targets microfluidic chips or auto-generated simulator Fluidic ISA BioStream Library Architecture Description - Double camera(Fluid f); Microfluidic chip Microfluidic simulator Simulator Generator User Code Fluid yellow = input (0); Fluid blue = input (1); Fluid[] out = new Fluid[8]; for (int i=0; i<=4; i++) out[i] = mix(yellow, 1-i/4, blue, i/4);

Applications in Progress 1. What are the best indicators for oocyte viability? -With Mark Johnson’s and Todd Thorsen’s groups -During in-vitro fertilization, monitor cell metabolites and select healthiest embryo for implantation 2. How do mammalian signal transduction pathways respond to complex inputs? -With Jeremy Gunawardena’s and Todd Thorsen’s groups -Isolate cells and stimulate with square wave, sine wave, etc.

Generating Complex Signals CellTrap cells = new CellTrap(); … // setup cell culture while (true) { float target = targetSignal(getTime()); Fluid f = mix(EGF, target, WATER, 1-target); cells.drainAndFill(f); cells.useAfter(10*SEC); } Video courtesy David Craig

Additional Applications Killer apps: react to feedback, redirect the experiment –Recursive-descent search –Fixed-pH reaction –Directed evolution –Long, complex protocols Application to biological computation –Many emerging technologies: DNA computing, cellular signaling, biomolecular automata, … –But not yet able to assemble, sustain, and adapt themselves –Microfluidics provides a scaffold to explore underlying biology Program Intelligence Biology Experiment

Compiler Optimizations

Algorithms for Efficient Mixing Mixing is fundamental operation of microfluidics –Prepare samples for analysis –Dilute concentrated substances –Control reagant volumes How to synthesize complex mixture using simple steps? –Many systems support only 50/50 mixers –Should minimize number of mixes, reagent usage –Note: some mixtures only reachable within error tolerance  N Analogous to ALU operations on microprocessors Interesting scheduling and optimization problem

Why Not Binary Search? 0 1 3/8 1/4 1/2 3/8 5 inputs, 4 mixes

Why Not Binary Search? 0 1 3/8 3/4 1/2 3/8 4 inputs, 3 mixes 1/4 1/2 3/8 5 inputs, 4 mixes

Min-Mix Algorithm Simple algorithm yields minimal number of mixes –For any number of reagents, to any reachable concentration –Also minimizes reagent usage on certain chips

1.The mixing process can be represented by a tree. Min-Mix Algorithm: Key Insights B A B A 5/8 A, 3/8 B

1.The mixing process can be represented by a tree. 2.The contribution of an input sample to the overall mixture is 2 -d, where d is the depth of the sample in the tree Min-Mix Algorithm: Key Insights B A B A 5/8 A, 3/8 B d d 1/8 1/4 1/2

1.The mixing process can be represented by a tree. 2.The contribution of an input sample to the overall mixture is 2 -d, where d is the depth of the sample in the tree 3.In the optimal mixing tree, a reagent appears at depths corresponding to the binary representation of its overall concentration. Min-Mix Algorithm: Key Insights B A B A 5/8 A, 3/8 B d d 1/8 1/4 1/2 3 = =

Min-Mix Algorithm Example: mix 5/16 A, 7/16 B, 4/16 C To mix k fluids with precision 1/n: –Min-mix algorithm: O(k log n) mixes –Binary search: O(k n) mixes B C A B A B A A B B B C 1/16 1/8 1/4 1/2 2 -d d A=5 B=7 C=4 =0101 =0111 =0100 [Natural Computing 2007]

Work In Progress

CAD Tools for Microfluidic Chips Microfluidic design tools are in their infancy –Most groups use Adobe Illustrator or AutoCAD –Limited automation; every line drawn by hand Due to fast fabrication, redesign is very frequent –Student can do multiple design cycles per week

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

First Step: Automatic Routing First target: automate the routing of control channels –Connecting valves to pneumatic ports is very tedious –Simple constraints govern the channel placement AutoCAD plugin automates this task –Developed With Nada Amin

Related Work Aquacore – builds on our work, ISA + architecture [Amin et al.] Automatic generation / scheduling of biology protocols –Robot scientist: generates/tests genetic hypotheses [King et al.] –EDNAC computer for automatically solving 3-SAT [Johnson] –Compile SAT to microfluidic chips [Landweber et al.] [van Noort] –Mapping sequence graphs to grid-based chips [Su/Chakrabarty] Custom microfluidic chips for biological computation –DNA computing [Grover & Mathies] [van Noort et al.] [McCaskill] [Livstone, Weiss, & Landweber] [Gehani & Reif] [Farfel & Stefanovic] –Self-assembly [Somei, Kaneda, Fujii, & Murata] [Whitesides et al.] General-purpose microfluidic chips –Using electrowetting, with flexible mixing [Fair et al.] –Using dialectrophoresis, with retargettable GUI [Gascoyne et al.] –Using Braille displays as programmable actuators [Gu et al.]

Conclusions Abstraction layers for programmable microfluidics –General-purpose chips –Fluidic ISA –BioStream language –Mixing algorithms Vision for microfluidics: everyone uses standard chip Vision for software: a defacto language for experimental science –Download a colleague’s code, run it on your chip –Compose modules and libraries to enable complex experiments that are impossible to perform today

Extra Slides

How Can Computer Scientists Contribute? Applying the ideas from our field to a new domain –Sometimes requires deep adaptations (e.g., digital gain) Our contributions: –First soft-lithography digital architecture with sample alignment –First demonstration of portability: same code, multiple chips –New high-level programming abstractions for microfluidics –First O(lg n) mixing algorithm for unit volumes (vs O(n)) Open problems: –Adapt unique (linear) types for microfluidics –Sound scheduling under timing constraints –Dynamic optimization of slow co-processors (lazy vectorization?) –Mixing algorithms for different ISA’s (e.g., lossless mixing) –Generate a CAD layout from a problem description