Skip to content

Commit

Permalink
support kernel handover with coherent time
Browse files Browse the repository at this point in the history
sbourdeauducq committed May 2, 2015
1 parent cb65b1e commit 4048568
Showing 10 changed files with 129 additions and 29 deletions.
9 changes: 4 additions & 5 deletions artiq/coredevice/comm_generic.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
from enum import Enum
from fractions import Fraction

from artiq.coredevice.runtime import Environment
from artiq.coredevice import runtime_exceptions
from artiq.language import core as core_language
from artiq.coredevice.rpc_wrapper import RPCWrapper
@@ -89,7 +88,7 @@ def _write_header(self, length, ty):
logger.debug("sending message: type=%r length=%d", ty, length)
self.write(struct.pack(">llB", 0x5a5a5a5a, length, ty.value))

def get_runtime_env(self):
def check_ident(self):
self._write_header(9, _H2DMsgType.IDENT_REQUEST)
_, ty = self._read_header()
if ty != _D2HMsgType.IDENT_REPLY:
@@ -102,7 +101,6 @@ def get_runtime_env(self):
if runtime_id != "AROR":
raise UnsupportedDevice("Unsupported runtime ID: {}"
.format(runtime_id))
return Environment()

def switch_clock(self, external):
self._write_header(10, _H2DMsgType.SWITCH_CLOCK)
@@ -118,8 +116,9 @@ def load(self, kcode):
if ty != _D2HMsgType.LOAD_COMPLETED:
raise IOError("Incorrect reply from device: "+str(ty))

def run(self, kname):
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
def run(self, kname, reset_now):
self._write_header(len(kname) + 10, _H2DMsgType.RUN_KERNEL)
self.write(struct.pack("B", reset_now))
self.write(bytes(kname, "ascii"))
logger.debug("running kernel: %s", kname)

19 changes: 12 additions & 7 deletions artiq/coredevice/core.py
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@
from artiq.transforms.lower_time import lower_time
from artiq.transforms.unparse import unparse

from artiq.coredevice.runtime import Environment

from artiq.py2llvm import get_runtime_binary


@@ -52,12 +54,10 @@ class DBKeys:
external_clock = Argument(False)

def build(self):
self.runtime_env = self.comm.get_runtime_env()
self.first_run = True
self.core = self
self.comm.core = self

self.comm.switch_clock(self.external_clock)
self.initial_time = int64(self.runtime_env.warmup_time/self.ref_period)
self.runtime_env = Environment()

def transform_stack(self, func_def, rpc_map, exception_map,
debug_unparse=_no_debug_unparse):
@@ -79,7 +79,7 @@ def transform_stack(self, func_def, rpc_map, exception_map,
interleave(func_def)
debug_unparse("interleave", func_def)

lower_time(func_def, self.initial_time)
lower_time(func_def)
debug_unparse("lower_time", func_def)

remove_inter_assigns(func_def)
@@ -113,17 +113,22 @@ def compile(self, k_function, k_args, k_kwargs, with_attr_writeback=True):
return binary, rpc_map, exception_map

def run(self, k_function, k_args, k_kwargs):
if self.first_run:
self.comm.check_ident()
self.comm.switch_clock(self.external_clock)

binary, rpc_map, exception_map = self.compile(
k_function, k_args, k_kwargs)
self.comm.load(binary)
self.comm.run(k_function.__name__)
self.comm.run(k_function.__name__, self.first_run)
self.comm.serve(rpc_map, exception_map)
self.first_run = False

@kernel
def get_rtio_time(self):
return cycles_to_time(syscall("rtio_get_counter"))

@kernel
def recover_underflow(self):
t = syscall("rtio_get_counter") + self.initial_time
t = syscall("rtio_get_counter") + 125000
at(cycles_to_time(t))
2 changes: 2 additions & 0 deletions artiq/coredevice/runtime.py
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@
llvm.initialize_all_asmprinters()

_syscalls = {
"now_init": "n:I",
"now_save": "I:n",
"watchdog_set": "i:i",
"watchdog_clear": "i:n",
"rtio_set_o": "Iib:n",
2 changes: 1 addition & 1 deletion artiq/frontend/artiq_run.py
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ class DBKeys:
def run(self):
with open(self.file, "rb") as f:
self.core.comm.load(f.read())
self.core.comm.run("run")
self.core.comm.run("run", False)
self.core.comm.serve(dict(), dict())


27 changes: 19 additions & 8 deletions artiq/transforms/lower_time.py
Original file line number Diff line number Diff line change
@@ -14,9 +14,6 @@

import ast

from artiq.transforms.tools import value_to_ast
from artiq.language.core import int64


class _TimeLowerer(ast.NodeTransformer):
def visit_Call(self, node):
@@ -45,9 +42,23 @@ def visit_Expr(self, node):
return r


def lower_time(func_def, initial_time):
def lower_time(func_def):
_TimeLowerer().visit(func_def)
func_def.body.insert(0, ast.copy_location(
ast.Assign(targets=[ast.Name("now", ast.Store())],
value=value_to_ast(int64(initial_time))),
func_def))
call_init = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("now_init")],
keywords=[], starargs=None, kwargs=None)
stmt_init = ast.Assign(targets=[ast.Name("now", ast.Store())],
value=call_init)
call_save = ast.Call(
func=ast.Name("syscall", ast.Load()),
args=[ast.Str("now_save"), ast.Name("now", ast.Load())],
keywords=[], starargs=None, kwargs=None)
stmt_save = ast.Expr(call_save)
func_def.body = [
stmt_init,
ast.Try(body=func_def.body,
handlers=[],
orelse=[],
finalbody=[stmt_save])
]
16 changes: 16 additions & 0 deletions examples/master/repository/handover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from artiq import *


class Handover(Experiment, AutoDB):
class DBKeys:
core = Device()
led = Device()

@kernel
def blink_once(self):
self.led.pulse(250*ms)
delay(250*ms)

def run(self):
while True:
self.blink_once()
2 changes: 2 additions & 0 deletions soc/runtime/gen_service_table.py
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@

services = [
("syscalls", [
("now_init", "now_init"),
("now_save", "now_save"),
("rpc", "rpc"),
("watchdog_set", "watchdog_set"),
("watchdog_clear", "watchdog_clear"),
47 changes: 40 additions & 7 deletions soc/runtime/ksupport.c
Original file line number Diff line number Diff line change
@@ -18,12 +18,12 @@ void exception_handler(unsigned long vect, unsigned long *sp);
void exception_handler(unsigned long vect, unsigned long *sp)
{
struct msg_exception msg;
int i;

msg.type = MESSAGE_TYPE_EXCEPTION;
msg.eid = EID_INTERNAL_ERROR;
for(i=0;i<3;i++)
msg.eparams[i] = 0;
msg.eparams[0] = 256;
msg.eparams[1] = 256;
msg.eparams[2] = 256;
mailbox_send_and_wait(&msg);
while(1);
}
@@ -51,8 +51,6 @@ int main(void)
} else {
struct msg_base msg;

dds_init();
rtio_init();
k();
exception_pop(1);

@@ -63,6 +61,41 @@ int main(void)
while(1);
}

long long int now_init(void);
long long int now_init(void)
{
struct msg_base request;
struct msg_now_init_reply *reply;
long long int now;

request.type = MESSAGE_TYPE_NOW_INIT_REQUEST;
mailbox_send_and_wait(&request);

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_NOW_INIT_REPLY)
exception_raise_params(EID_INTERNAL_ERROR, 1, 0, 0);
now = reply->now;
mailbox_acknowledge();

if(now < 0) {
dds_init();
rtio_init();
now = 125000;
}

return now;
}

void now_save(long long int now);
void now_save(long long int now)
{
struct msg_now_save request;

request.type = MESSAGE_TYPE_NOW_SAVE;
request.now = now;
mailbox_send_and_wait(&request);
}

int watchdog_set(int ms)
{
struct msg_watchdog_set_request request;
@@ -75,7 +108,7 @@ int watchdog_set(int ms)

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_WATCHDOG_SET_REPLY)
exception_raise(EID_INTERNAL_ERROR);
exception_raise_params(EID_INTERNAL_ERROR, 2, 0, 0);
id = reply->id;
mailbox_acknowledge();

@@ -105,7 +138,7 @@ int rpc(int rpc_num, ...)

reply = mailbox_wait_and_receive();
if(reply->type != MESSAGE_TYPE_RPC_REPLY)
exception_raise(EID_INTERNAL_ERROR);
exception_raise_params(EID_INTERNAL_ERROR, 3, 0, 0);
eid = reply->eid;
retval = reply->retval;
mailbox_acknowledge();
13 changes: 13 additions & 0 deletions soc/runtime/messages.h
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@
#include <stdarg.h>

enum {
MESSAGE_TYPE_NOW_INIT_REQUEST,
MESSAGE_TYPE_NOW_INIT_REPLY,
MESSAGE_TYPE_NOW_SAVE,
MESSAGE_TYPE_FINISHED,
MESSAGE_TYPE_EXCEPTION,
MESSAGE_TYPE_WATCHDOG_SET_REQUEST,
@@ -30,6 +33,16 @@ struct msg_base {

/* kernel messages */

struct msg_now_init_reply {
int type;
long long int now;
};

struct msg_now_save {
int type;
long long int now;
};

struct msg_exception {
int type;
int eid;
21 changes: 20 additions & 1 deletion soc/runtime/session.c
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ static void submit_output(int len)
}

static int user_kernel_state;
static long long int now;

enum {
USER_KERNEL_NONE = 0,
@@ -167,7 +168,10 @@ static int process_input(void)
}
buffer_in[buffer_in_index] = 0;

k = kloader_find((char *)&buffer_in[9]);
if(buffer_in[9])
now = -1;

k = kloader_find((char *)&buffer_in[10]);
if(k == NULL) {
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
@@ -394,6 +398,21 @@ static int process_kmsg(struct msg_base *umsg)
return 0;

switch(umsg->type) {
case MESSAGE_TYPE_NOW_INIT_REQUEST: {
struct msg_now_init_reply reply;

reply.type = MESSAGE_TYPE_NOW_INIT_REPLY;
reply.now = now;
mailbox_send_and_wait(&reply);
break;
}
case MESSAGE_TYPE_NOW_SAVE: {
struct msg_now_save *msg = (struct msg_now_save *)umsg;

now = msg->now;
mailbox_acknowledge();
break;
}
case MESSAGE_TYPE_FINISHED:
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_FINISHED;
submit_output(9);

0 comments on commit 4048568

Please sign in to comment.