Commit ac0a684e authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

minor updates to quil compiler for qcor support


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 0751fa99
Pipeline #101362 passed with stage
in 69 minutes and 39 seconds
......@@ -44,7 +44,7 @@
compile_commands.json
/docs/doxygen/html**
**/*.dat
**/.antlr
# IDE files
.vscode/*
.theia/*
\ No newline at end of file
.theia/*
......@@ -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
......@@ -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()) {
......
......@@ -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;
/**
*
......
......@@ -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);
}
......
......@@ -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();
......
......@@ -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