Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ORNL Quantum Computing Institute
xacc
Commits
ac0a684e
Commit
ac0a684e
authored
Apr 28, 2020
by
Mccaskey, Alex
Browse files
minor updates to quil compiler for qcor support
Signed-off-by:
Alex McCaskey
<
mccaskeyaj@ornl.gov
>
parent
0751fa99
Pipeline
#101362
passed with stage
in 69 minutes and 39 seconds
Changes
18
Pipelines
16
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
ac0a684e
...
...
@@ -44,7 +44,7 @@
compile_commands.json
/docs/doxygen/html**
**/*.dat
**/.antlr
# IDE files
.vscode/*
.theia/*
\ No newline at end of file
.theia/*
quantum/plugins/rigetti/compiler/Quil.g4
View file @
ac0a684e
...
...
@@ -2,236 +2,233 @@ grammar Quil;
/* This part of the grammar is particular to XACC */
/***********************************************************************/
xaccsrc
: ( xacckernel NEWLINE* )*
;
xacckernel
: '__qpu__' 'void' kernelname=IDENTIFIER '(' 'qbit' acceleratorbuffer=IDENTIFIER ( ',' typedparam )* ')' '{' quil '}'
;
typedparam
: type IDENTIFIER
;
type
: 'int'
| 'double'
| 'float'
;
kernelcall
: kernelname=IDENTIFIER '(' IDENTIFIER? ( ',' IDENTIFIER )* ')'
;
xaccsrc: xacckernel;
xacckernel:
'__qpu__' 'void' kernelname = id '(' typedparam (
',' typedparam
)* ')' '{' quil '}';
typedparam: type ('&' | '*')? variable_param_name;
variable_param_name: id;
type:
'int'
| id ('<' id (',' id)? '>')?
| id '::' id ('<' id (',' id)? '>')?
| 'std::shared_ptr<' type '>';
id: IDENTIFIER;
kernelcall:
kernelname = IDENTIFIER '(' IDENTIFIER? (',' IDENTIFIER)* ')';
/***********************************************************************/
////////////////////
// PARSER
////////////////////
quil : allInstr? (NEWLINE+ allInstr)* NEWLINE* ;
allInstr : defGate
| defCircuit
| instr
| kernelcall
;
instr : gate
| measure
| defLabel
| halt
| jump
| jumpWhen
| jumpUnless
| resetState
| wait
| classicalUnary
| classicalBinary
| nop
| include
| pragma
;
// PARSER //////////////////
quil: allInstr? (NEWLINE+ allInstr)* NEWLINE*;
allInstr: defGate | defCircuit | instr | kernelcall;
instr:
gate
| measure
| defLabel
| halt
| jump
| jumpWhen
| jumpUnless
| resetState
| wait
| classicalUnary
| classicalBinary
| nop
| include
| pragma;
// C. Static and Parametric Gates
gate
: name (LPAREN param (COMMA param)* RPAREN)? qubit+
;
gate: name (LPAREN param (COMMA param)* RPAREN)? qubit+;
name
: IDENTIFIER
;
qubit
: INT
;
name: IDENTIFIER;
qubit: INT;
param
: expression
;
param: expression;
// D. Gate Definitions
defGate : DEFGATE name (LPAREN variable (COMMA variable)* RPAREN)? COLON NEWLINE matrix ;
defGate:
DEFGATE name (LPAREN variable (COMMA variable)* RPAREN)? COLON NEWLINE matrix;
variable
: PERCENTAGE IDENTIFIER
;
variable: PERCENTAGE IDENTIFIER;
matrix
: (matrixRow NEWLINE)* matrixRow
;
matrixRow
: TAB expression (COMMA expression)*
;
matrix: (matrixRow NEWLINE)* matrixRow;
matrixRow: TAB expression (COMMA expression)*;
// E. Circuits
defCircuit : DEFCIRCUIT name (LPAREN variable (COMMA variable)* RPAREN)? qubitVariable* COLON NEWLINE circuit ;
defCircuit:
DEFCIRCUIT name (LPAREN variable (COMMA variable)* RPAREN)? qubitVariable* COLON NEWLINE circuit
;
qubitVariable
: IDENTIFIER
;
qubitVariable: IDENTIFIER;
circuitQubit : qubit | qubitVariable ;
circuitGate : name (LPAREN param (COMMA param)* RPAREN)? circuitQubit+ ;
circuitInstr : circuitGate | instr ;
circuit : (TAB circuitInstr NEWLINE)* TAB circuitInstr ;
circuitQubit: qubit | qubitVariable;
circuitGate:
name (LPAREN param (COMMA param)* RPAREN)? circuitQubit+;
circuitInstr: circuitGate | instr;
circuit: (TAB circuitInstr NEWLINE)* TAB circuitInstr;
// F. Measurement
measure
: MEASURE qubit addr?
;
addr
: LBRACKET classicalBit RBRACKET
;
classicalBit
: INT+
;
measure: MEASURE qubit addr?;
addr: LBRACKET classicalBit RBRACKET;
classicalBit: INT+;
// G. Program control
defLabel
: LABEL label
;
label
: AT IDENTIFIER
;
halt
: HALT
;
jump
: JUMP label
;
jumpWhen
: JUMPWHEN label addr
;
jumpUnless
: JUMPUNLESS label addr
;
defLabel: LABEL label;
label: AT IDENTIFIER;
halt: HALT;
jump: JUMP label;
jumpWhen: JUMPWHEN label addr;
jumpUnless: JUMPUNLESS label addr;
// H. Zeroing the Quantum State
resetState : RESET ; // NB: cannot be named "reset" due to conflict with Antlr implementation
resetState:
RESET; // NB: cannot be named "reset" due to conflict with Antlr implementation
// I. Classical/Quantum Synchronization
wait
: WAIT
;
wait: WAIT;
// J. Classical Instructions
classicalUnary
: (TRUE | FALSE | NOT) addr
;
classicalBinary
: (AND | OR | MOVE | EXCHANGE) addr addr
;
classicalUnary: (TRUE | FALSE | NOT) addr;
classicalBinary: (AND | OR | MOVE | EXCHANGE) addr addr;
// K. The No-Operation Instruction
nop
: NOP
;
nop: NOP;
// L. File Inclusion
include
: INCLUDE STRING
;
include: INCLUDE STRING;
// M. Pragma Support
pragma
: PRAGMA IDENTIFIER pragma_name* STRING?
;
pragma_name
: IDENTIFIER | INT
;
pragma: PRAGMA IDENTIFIER pragma_name* STRING?;
pragma_name: IDENTIFIER | INT;
// Expressions (in order of precedence)
expression : LPAREN expression RPAREN #parenthesisExp
| sign expression #signedExp
| <assoc=right> expression POWER expression #powerExp
| expression (TIMES | DIVIDE) expression #mulDivExp
| expression (PLUS | MINUS) expression #addSubExp
| function LPAREN expression RPAREN #functionExp
| segment #segmentExp
| number #numberExp
| variable #variableExp
| IDENTIFIER #identifierExp // An XACC parameter
;
segment : LBRACKET INT MINUS INT RBRACKET ;
function : SIN | COS | SQRT | EXP | CIS ;
sign : PLUS | MINUS ;
expression:
LPAREN expression RPAREN # parenthesisExp
| sign expression # signedExp
| <assoc = right> expression POWER expression # powerExp
| expression (TIMES | DIVIDE) expression # mulDivExp
| expression (PLUS | MINUS) expression # addSubExp
| function LPAREN expression RPAREN # functionExp
| segment # segmentExp
| number # numberExp
| variable # variableExp
| IDENTIFIER # identifierExp ; // An XACC parameter
// Numbers
// We suffix -N onto these names so they don't conflict with already defined Python types
segment: LBRACKET INT MINUS INT RBRACKET;
function: SIN | COS | SQRT | EXP | CIS;
sign: PLUS | MINUS;
number : realN | imaginaryN | I | PI ;
imaginaryN : realN I ;
realN : FLOAT | INT ;
// Numbers We suffix -N onto these names so they don't conflict with already defined Python types
number: realN | imaginaryN | I | PI;
imaginaryN: realN I;
realN: FLOAT | INT;
////////////////////
// LEXER
////////////////////
// LEXER //////////////////
// Keywords
DEFGATE
: 'DEFGATE'
;
DEFCIRCUIT
: 'DEFCIRCUIT'
;
MEASURE
: 'MEASURE'
;
LABEL
: 'LABEL'
;
HALT
: 'HALT'
;
JUMP
: 'JUMP'
;
JUMPWHEN
: 'JUMP-WHEN'
;
JUMPUNLESS
: 'JUMP-UNLESS'
;
RESET
: 'RESET'
;
WAIT
: 'WAIT'
;
NOP
: 'NOP'
;
INCLUDE
: 'INCLUDE'
;
PRAGMA
: 'PRAGMA'
;
FALSE
: 'FALSE'
;
TRUE
: 'TRUE'
;
NOT
: 'NOT'
;
AND
: 'AND'
;
OR
: 'OR'
;
MOVE
: 'MOVE'
;
EXCHANGE
: 'EXCHANGE'
;
PI
: 'pi'
;
I
: 'i'
;
SIN
: 'sin'
;
COS
: 'cos'
;
SQRT
: 'sqrt'
;
EXP
: 'exp'
;
CIS
: 'cis'
;
DEFGATE: 'DEFGATE';
DEFCIRCUIT: 'DEFCIRCUIT';
MEASURE: 'MEASURE';
LABEL: 'LABEL';
HALT: 'HALT';
JUMP: 'JUMP';
JUMPWHEN: 'JUMP-WHEN';
JUMPUNLESS: 'JUMP-UNLESS';
RESET: 'RESET';
WAIT: 'WAIT';
NOP: 'NOP';
INCLUDE: 'INCLUDE';
PRAGMA: 'PRAGMA';
FALSE: 'FALSE';
TRUE: 'TRUE';
NOT: 'NOT';
AND: 'AND';
OR: 'OR';
MOVE: 'MOVE';
EXCHANGE: 'EXCHANGE';
PI: 'pi';
I: 'i';
SIN: 'sin';
COS: 'cos';
SQRT: 'sqrt';
EXP: 'exp';
CIS: 'cis';
// Operators
PLUS
: '+'
;
MINUS
: '-'
; // Also serves as range in expressions like [8-71]
TIMES
: '*'
;
DIVIDE
: '/'
;
POWER
: '^'
;
PLUS: '+';
MINUS: '-'; // Also serves as range in expressions like [8-71]
TIMES: '*';
DIVIDE: '/';
POWER: '^';
// Identifiers
IDENTIFIER
: [A-Za-z_] [A-Za-z0-9\-_]*
;
IDENTIFIER: [A-Za-z_] [A-Za-z0-9\-_]*;
// Numbers
INT
: [0-9]+
;
FLOAT
: [0-9]+ ('.' [0-9]+)? (('e'
|
'E') ('+' | '-')? [0-9]+)?
;
INT: [0-9]+;
FLOAT: [0-9]+ ('.' [0-9]+)? (('e'
|
'E') ('+' | '-')? [0-9]+)?;
// String
STRING
: '"' ~('\n' | '\r')* '"';
STRING: '"' ~('\n' | '\r')* '"';
// Punctuation
PERIOD
: '.'
;
COMMA
: ','
;
LPAREN
: '('
;
RPAREN
: ')'
;
LBRACKET
: '['
;
RBRACKET
: ']'
;
COLON
: ':'
;
PERCENTAGE
: '%'
;
AT
: '@'
;
QUOTE
: '"'
;
UNDERSCORE
: '_'
;
PERIOD: '.';
COMMA: ',';
LPAREN: '(';
RPAREN: ')';
LBRACKET: '[';
RBRACKET: ']';
COLON: ':';
PERCENTAGE: '%';
AT: '@';
QUOTE: '"';
UNDERSCORE: '_';
// Whitespace
TAB
: ' '
;
NEWLINE
: ('\r'? '\n' | '\r')+
;
TAB: ' ';
NEWLINE: ('\r'? '\n' | '\r')+;
// Skips
COMMENT
: '#' ~('\n' | '\r')* -> skip
;
SPACE
: ' ' -> skip
;
COMMENT: '#' ~('\n' | '\r')* -> skip;
SPACE: ' ' -> skip;
// Error
INVALID : . ;
\ No newline at end of file
INVALID: .;
\ No newline at end of file
quantum/plugins/rigetti/compiler/QuilCompiler.cpp
View file @
ac0a684e
...
...
@@ -29,6 +29,34 @@ namespace quantum {
QuilCompiler
::
QuilCompiler
()
=
default
;
bool
QuilCompiler
::
canParse
(
const
std
::
string
&
src
)
{
class
QuilThrowExceptionErrorListener
:
public
BaseErrorListener
{
public:
void
syntaxError
(
Recognizer
*
recognizer
,
Token
*
offendingSymbol
,
size_t
line
,
size_t
charPositionInLine
,
const
std
::
string
&
msg
,
std
::
exception_ptr
e
)
override
{
std
::
cout
<<
"Quil Cannot parse this source: "
<<
msg
<<
"
\n
"
;
std
::
cout
<<
line
<<
": "
<<
charPositionInLine
<<
"
\n
"
;
std
::
cout
<<
offendingSymbol
->
getText
()
<<
"
\n
"
;
throw
std
::
runtime_error
(
"Cannot parse this Quil source string."
);
}
};
ANTLRInputStream
input
(
src
);
QuilLexer
lexer
(
&
input
);
CommonTokenStream
tokens
(
&
lexer
);
QuilParser
parser
(
&
tokens
);
parser
.
removeErrorListeners
();
parser
.
addErrorListener
(
new
QuilThrowExceptionErrorListener
());
try
{
tree
::
ParseTree
*
tree
=
parser
.
xaccsrc
();
return
true
;
}
catch
(
std
::
exception
&
e
)
{
return
false
;
}
}
std
::
shared_ptr
<
IR
>
QuilCompiler
::
compile
(
const
std
::
string
&
src
,
std
::
shared_ptr
<
Accelerator
>
acc
)
{
...
...
@@ -54,10 +82,11 @@ std::shared_ptr<IR> QuilCompiler::compile(const std::string &src,
return
ir
;
}
std
::
shared_ptr
<
IR
>
QuilCompiler
::
compile
(
const
std
::
string
&
src
)
{
return
compile
(
src
,
nullptr
);
return
compile
(
src
,
nullptr
);
}
const
std
::
string
QuilCompiler
::
translate
(
std
::
shared_ptr
<
CompositeInstruction
>
function
)
{
const
std
::
string
QuilCompiler
::
translate
(
std
::
shared_ptr
<
CompositeInstruction
>
function
)
{
auto
visitor
=
std
::
make_shared
<
QuilVisitor
>
();
InstructionIterator
it
(
function
);
while
(
it
.
hasNext
())
{
...
...
quantum/plugins/rigetti/compiler/QuilCompiler.hpp
View file @
ac0a684e
...
...
@@ -35,6 +35,7 @@ public:
*/
virtual
std
::
shared_ptr
<
xacc
::
IR
>
compile
(
const
std
::
string
&
src
,
std
::
shared_ptr
<
Accelerator
>
acc
);
bool
canParse
(
const
std
::
string
&
src
)
override
;
/**
*
...
...
quantum/plugins/rigetti/compiler/QuilToXACCListener.cpp
View file @
ac0a684e
...
...
@@ -25,17 +25,36 @@ namespace quantum {
QuilToXACCListener
::
QuilToXACCListener
()
{
gateRegistry
=
xacc
::
getService
<
IRProvider
>
(
"quantum"
);
parsingUtil
=
xacc
::
getService
<
ExpressionParsingUtil
>
(
"exprtk"
);
}
void
QuilToXACCListener
::
enterXacckernel
(
quil
::
QuilParser
::
XacckernelContext
*
ctx
)
{
std
::
vector
<
std
::
string
>
params
;
// std::vector<std::string> params;
// for (int i = 0; i < ctx->typedparam().size(); i++) {
// params.push_back(
// ctx->typedparam(i)->IDENTIFIER()->getText());
// }
// function =
// gateRegistry->createComposite(ctx->kernelname->getText(), params);
std
::
vector
<
std
::
string
>
variables
,
validTypes
{
"double"
,
"float"
,
"std::vector<double>"
,
"int"
};
function
=
gateRegistry
->
createComposite
(
ctx
->
kernelname
->
getText
());
for
(
int
i
=
0
;
i
<
ctx
->
typedparam
().
size
();
i
++
)
{
params
.
push_back
(
ctx
->
typedparam
(
i
)
->
IDENTIFIER
()
->
getText
());
auto
type
=
ctx
->
typedparam
(
i
)
->
type
()
->
getText
();
auto
vname
=
ctx
->
typedparam
(
i
)
->
variable_param_name
()
->
getText
();
function
->
addArgument
(
vname
,
type
);
// if (type == "qreg" || type == "qbit") {
// functionBufferNames.push_back(vname);
// }
if
(
xacc
::
container
::
contains
(
validTypes
,
ctx
->
typedparam
(
i
)
->
type
()
->
getText
()))
{
variables
.
push_back
(
vname
);
}
}
function
=
gateRegistry
->
createComposite
(
ctx
->
kernelname
->
getText
(),
params
);
function
->
addVariables
(
variables
);
}
void
QuilToXACCListener
::
exitKernelcall
(
...
...
@@ -61,15 +80,32 @@ void QuilToXACCListener::exitGate(quil::QuilParser::GateContext *ctx) {
qubits
.
push_back
(
std
::
stoi
(
ctx
->
qubit
(
i
)
->
getText
()));
}
std
::
map
<
int
,
std
::
shared_ptr
<
CompositeArgument
>>
args
;
std
::
vector
<
InstructionParameter
>
params
;
for
(
int
i
=
0
;
i
<
ctx
->
param
().
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
ctx
->
param
().
size
();
i
++
)
{
auto
paramStr
=
ctx
->
param
(
i
)
->
getText
();
params
.
emplace_back
(
paramStr
);
// params.emplace_back(paramStr);
double
value
;
if
(
parsingUtil
->
isConstant
(
ctx
->
param
(
i
)
->
getText
(),
value
))
{
xacc
::
debug
(
"[XasmCompiler] Parameter added is "
+
std
::
to_string
(
value
));
params
.
emplace_back
(
value
);
}
else
{
xacc
::
debug
(
"[XasmCompiler] Parameter added is "
+
ctx
->
param
(
i
)
->
getText
());
params
.
emplace_back
(
ctx
->
param
(
i
)
->
getText
());
// This depends on a function argument
auto
arg
=
function
->
getArgument
(
ctx
->
param
(
i
)
->
getText
());
args
.
insert
({
i
,
arg
});
}
}
std
::
shared_ptr
<
xacc
::
Instruction
>
instruction
=
gateRegistry
->
createInstruction
(
gateName
,
qubits
,
params
);
for
(
auto
&
kv
:
args
)
instruction
->
addArgument
(
kv
.
second
,
kv
.
first
);
function
->
addInstruction
(
instruction
);
}
...
...
quantum/plugins/rigetti/compiler/QuilToXACCListener.hpp
View file @
ac0a684e
...
...
@@ -16,6 +16,7 @@
#include
"QuilBaseListener.h"
#include
"IR.hpp"
#include
"IRProvider.hpp"
#include
"expression_parsing_util.hpp"
using
namespace
quil
;
...
...
@@ -25,6 +26,7 @@ class QuilToXACCListener : public QuilBaseListener {
protected:
std
::
shared_ptr
<
IRProvider
>
gateRegistry
;
std
::
shared_ptr
<
CompositeInstruction
>
function
;
std
::
shared_ptr
<
ExpressionParsingUtil
>
parsingUtil
;
public:
QuilToXACCListener
();
...
...
quantum/plugins/rigetti/compiler/generated/Quil.interp
View file @
ac0a684e
This diff is collapsed.
Click to expand it.
quantum/plugins/rigetti/compiler/generated/Quil.tokens
View file @
ac0a684e
...
...
@@ -6,108 +6,112 @@ T__4=5
T__5=6
T__6=7
T__7=8
DEFGATE=9
DEFCIRCUIT=10
MEASURE=11
LABEL=12
HALT=13
JUMP=14
JUMPWHEN=15
JUMPUNLESS=16
RESET=17
WAIT=18
NOP=19
INCLUDE=20
PRAGMA=21
FALSE=22
TRUE=23
NOT=24
AND=25
OR=26
MOVE=27
EXCHANGE=28
PI=29
I=30
SIN=31
COS=32
SQRT=33
EXP=34
CIS=35
PLUS=36
MINUS=37
TIMES=38
DIVIDE=39
POWER=40
IDENTIFIER=41
INT=42
FLOAT=43
STRING=44
PERIOD=45
COMMA=46
LPAREN=47
RPAREN=48
LBRACKET=49
RBRACKET=50
COLON=51
PERCENTAGE=52
AT=53
QUOTE=54
UNDERSCORE=55
TAB=56
NEWLINE=57
COMMENT=58
SPACE=59
INVALID=60
T__8=9
T__9=10
DEFGATE=11
DEFCIRCUIT=12
MEASURE=13
LABEL=14
HALT=15
JUMP=16
JUMPWHEN=17
JUMPUNLESS=18
RESET=19
WAIT=20