import seamless from seamless.core import macro_mode_on from seamless.core import context, cell, \ macro, path def run_macro(ctx): ctx.mycell = cell() with macro_mode_on(): ctx = context(toplevel=True) ctx.macro = macro({}) ctx.macro.code.cell().set(run_macro) ctx.a = cell().set(1) p = path(ctx.macro.ctx).mycell ctx.a.connect(p) ctx.aa = cell() p.connect(ctx.aa) ctx.compute() print(ctx.macro.ctx.mycell.value) print(ctx.aa.value) ctx.a.set(None) ctx.compute() print(ctx.macro.ctx.mycell.value) print(ctx.aa.value)
ctx.tf.result.connect(ctx.result) ctx.macro = macro({ "header": "str", "code_": { "celltype": "str", "as": "code", }, }) def run(ctx, code, header): ctx.result = cell("str").set("MACRO: " + header + code) ctx.macro.code.set(run) ctx.code.connect(ctx.macro.code_) ctx.header.connect(ctx.macro.header) ctx.result2 = cell("str") mctx = path(ctx.macro.ctx) mctx.result.connect(ctx.result2) ctx.reactor = reactor({ "header": "input", "code_": { "io": "input", "as": "code", }, "result": "output" }) ctx.code.connect(ctx.reactor.code_) ctx.header.connect(ctx.reactor.header) ctx.reactor.code_start.cell().set("") ctx.reactor.code_update.cell().set( "PINS.result.set('REACTOR: ' + PINS.header.value + PINS.code.value)"
def top(ctx, elision_, elision_chunksize, graph, lib_module_dict, lib_codeblock, inp, keyorder, has_uniform): ctx.lib_module_dict = cell("plain").set(lib_module_dict) ctx.lib_codeblock = cell("plain").set(lib_codeblock) ctx.main_code = cell("python").set(lib_module_dict["map_dict"]["main"]) ctx.lib_module = cell("plain").set({ "type": "interpreted", "language": "python", "code": lib_codeblock }) ctx.graph = cell("plain").set(graph) ctx.elision = cell("bool").set(elision_) ctx.elision_chunksize = cell("int").set(elision_chunksize) ctx.has_uniform = cell("bool").set(has_uniform) if has_uniform: ctx.uniform = cell("mixed") macro_params = { 'elision_': { 'celltype': 'bool' }, 'elision_chunksize': { 'celltype': 'int' }, 'graph': { 'celltype': 'plain' }, 'lib_module_dict': { 'celltype': 'plain' }, 'lib_codeblock': { 'celltype': 'plain' }, 'lib': { 'celltype': 'plain', 'subcelltype': 'module' }, 'inp': { 'celltype': 'plain' }, 'keyorder': { 'celltype': 'plain' }, 'has_uniform': { 'celltype': 'bool' }, } ctx.top = macro(macro_params) m = ctx.top m.allow_elision = elision_ ctx.main_code.connect(m.code) ctx.elision.connect(m.elision_) ctx.elision_chunksize.connect(m.elision_chunksize) ctx.has_uniform.connect(m.has_uniform) ctx.graph.connect(m.graph) ctx.lib_module_dict.connect(m.lib_module_dict) ctx.lib_codeblock.connect(m.lib_codeblock) ctx.lib_module.connect(m.lib) m.inp.cell().set(inp) m.keyorder.cell().set(keyorder) result_path = path(m.ctx).result ctx.result = cell("mixed", hash_pattern={"*": "#"}) result_path.connect(ctx.result) input_cells = {} if has_uniform: uniform_path = path(m.ctx).uniform ctx.uniform.connect(uniform_path) input_cells = {ctx.uniform: uniform_path} ctx._get_manager().set_elision(macro=m, input_cells=input_cells, output_cells={ ctx.result: result_path, })
def map_dict_nested(ctx, elision, elision_chunksize, graph, inp, keyorder, *, lib_module_dict, lib_codeblock, lib, has_uniform): from seamless.core import cell, macro, context, path, transformer assert len(inp) == len(keyorder) length = len(inp) #print("NEST", length, keyorder[0]) if elision and elision_chunksize > 1 and length > elision_chunksize: merge_subresults = lib_module_dict["helper"]["merge_subresults_dict"] ctx.lib_module_dict = cell("plain").set(lib_module_dict) ctx.lib_codeblock = cell("plain").set(lib_codeblock) ctx.main_code = cell("python").set(lib_module_dict["map_dict"]["main"]) ctx.lib_module = cell("plain").set({ "type": "interpreted", "language": "python", "code": lib_codeblock }) ctx.graph = cell("plain").set(graph) ctx.elision = cell("bool").set(elision) ctx.elision_chunksize = cell("int").set(elision_chunksize) ctx.has_uniform = cell("bool").set(has_uniform) chunk_index = 0 macro_params = { 'elision_': { 'celltype': 'bool' }, 'elision_chunksize': { 'celltype': 'int' }, 'graph': { 'celltype': 'plain' }, "lib_module_dict": { 'celltype': 'plain' }, "lib_codeblock": { 'celltype': 'plain' }, "lib": { 'celltype': 'plain', 'subcelltype': 'module' }, 'inp': { 'celltype': 'plain' }, 'has_uniform': { 'celltype': 'bool' }, 'keyorder': { 'celltype': 'plain' }, } if has_uniform: ctx.uniform = cell("mixed") subresults = {} chunksize = elision_chunksize while chunksize * elision_chunksize < length: chunksize *= elision_chunksize for n in range(0, length, chunksize): chunk_keyorder = keyorder[n:n + chunksize] chunk_inp = {k: inp[k] for k in chunk_keyorder} chunk_index += 1 subresult = cell("checksum") m = macro(macro_params) m.allow_elision = True setattr(ctx, "m{}".format(chunk_index), m) ctx.main_code.connect(m.code) ctx.elision.connect(m.elision_) ctx.elision_chunksize.connect(m.elision_chunksize) ctx.has_uniform.connect(m.has_uniform) ctx.graph.connect(m.graph) ctx.lib_module_dict.connect(m.lib_module_dict) ctx.lib_codeblock.connect(m.lib_codeblock) ctx.lib_module.connect(m.lib) m.inp.cell().set(chunk_inp) m.keyorder.cell().set(chunk_keyorder) subr = "subresult{}".format(chunk_index) setattr(ctx, subr, subresult) subresults[subr] = subresult result_path = path(m.ctx).result result_path.connect(subresult) input_cells = {} if has_uniform: uniform_path = path(m.ctx).uniform ctx.uniform.connect(uniform_path) input_cells = {ctx.uniform: uniform_path} ctx._get_manager().set_elision(macro=m, input_cells=input_cells, output_cells={ subresult: result_path, }) transformer_params = {} for subr in subresults: transformer_params[subr] = {"io": "input", "celltype": "checksum"} transformer_params["result"] = {"io": "output", "celltype": "checksum"} ctx.merge_subresults = transformer(transformer_params) ctx.merge_subresults.code.cell().set(merge_subresults) tf = ctx.merge_subresults for subr, c in subresults.items(): c.connect(getattr(tf, subr)) ctx.all_subresults = cell("plain") tf.result.connect(ctx.all_subresults) # ctx.all_subresults has the correct checksum, but there is no valid conversion # (because it is unsafe). # Use a macro to do it ctx.get_result = macro( {"result_checksum": { "io": "input", "celltype": "checksum" }}) get_result = lib_module_dict["helper"]["get_result_dict"] ctx.get_result.code.cell().set(get_result) ctx.all_subresults.connect(ctx.get_result.result_checksum) p = path(ctx.get_result.ctx).result ctx.result = cell("mixed", hash_pattern={"*": "#"}) p.connect(ctx.result) else: lib.map_dict(ctx, graph, inp, has_uniform, elision) return ctx
""") ctx.macro_code.connect(ctx.macro.code) ctx.tfx = transformer({ "x0": "input", "x": "output" }) ctx.tfx.code.cell().set("x = x0 + '!'") ctx.macro.ctx.x0.connect(ctx.tfx.x0) ctx.x = cell("text") ctx.tfx.x.connect(ctx.macro.ctx.x_link) ctx.tfx.x.connect(ctx.x) ctx.y = cell("text") ctx.macro.ctx.y.connect(ctx.y) ctx.e = cell("json") ctx.e2 = cell("json") p_d = path(ctx.macro.ctx).d p_d.connect(ctx.e) p_tf2 = path(ctx.macro.ctx).tf2 ctx.e.connect(p_tf2.e) p_tf2.e2.connect(ctx.e2) ctx.z = cell("text").set("z") ctx.z_link = link(ctx.z) ctx.z_link.connect(ctx.macro.ctx.z) ctx.q = cell("text") ctx.macro.ctx.q_link.connect(ctx.q) ctx.macro.ctx.q.connect(ctx.macro.ctx.qq) ctx.r = cell("text") ctx.r_link = link(ctx.r) ctx.macro.ctx.r_link.connect(ctx.r_link) ctx.r.connect(ctx.macro.ctx.rr_link)
def map_dict_chunk(ctx, chunksize, graph, inp, keyorder, has_uniform, elision, lib_module_dict): #print("map_dict_chunk", inp) from seamless.core import Cell as CoreCell from seamless.core import cell, context, macro, path, transformer from seamless.core.structured_cell import StructuredCell from seamless.core.HighLevelContext import HighLevelContext from seamless.core.unbound_context import UnboundContext import math pseudo_connections = [] ctx.sc_data = cell("mixed") ctx.sc_buffer = cell("mixed") inpkeys = keyorder nchunks = math.ceil(len(inpkeys) / chunksize) ctx.sc = StructuredCell( data=ctx.sc_data, buffer=ctx.sc_buffer, inchannels=[(n + 1, ) for n in range(nchunks)], outchannels=[()], ) if has_uniform: ctx.uniform = cell("mixed") first = True for n in range(nchunks): pos = chunksize * n hc = HighLevelContext(graph) subctx = "subctx_" + str(n + 1) setattr(ctx, subctx, hc) if first: if not hasattr(hc, "inp"): raise TypeError( "map_dict_chunk context must have a cell called 'inp'") hci = hc.inp if has_uniform: if first: if not hasattr(hc, "uniform"): raise TypeError( "map_dict_chunk context must have a cell called 'uniform'" ) if isinstance(hc.uniform, StructuredCell): raise TypeError( "map_dict_chunk context has a cell called 'uniform', but its celltype must be mixed, not structured" ) if not isinstance(hc.uniform, CoreCell): raise TypeError( "map_dict_chunk context must have an attribute 'uniform' that is a cell, not a {}" .format(type(hc.uniform))) ctx.uniform.connect(hc.uniform) con = ["..uniform"], ["ctx", subctx, "uniform"] pseudo_connections.append(con) if first: if isinstance(hci, StructuredCell): raise TypeError( "map_dict_chunk context has a cell called 'inp', but its celltype must be mixed, not structured" ) if not isinstance(hci, CoreCell): raise TypeError( "map_dict_chunk context must have an attribute 'inp' that is a cell, not a {}" .format(type(hci))) if hci.celltype != "mixed": raise TypeError( "map_dict_chunk context has a cell called 'inp', but its celltype must be mixed, not {}" .format(hci.celltype)) con = ["..inp"], ["ctx", subctx, "inp"] pseudo_connections.append(con) inputchunk = {k: inp[k] for k in inpkeys[pos:pos + chunksize]} #print("CHUNK", list(inputchunk.keys())) chunk_ctx = context() setattr(ctx, "chunk_%d" % (n + 1), chunk_ctx) chunk_ctx.inputchunk_deep = cell("mixed", hash_pattern={"*": "#"}) chunk_ctx.inputchunk_deep.set(inputchunk) chunk_ctx.inputchunk_deep2 = cell("plain") chunk_ctx.inputchunk_deep.connect(chunk_ctx.inputchunk_deep2) chunk_ctx.inputchunk_checksum = cell("checksum") chunk_ctx.inputchunk_deep2.connect(chunk_ctx.inputchunk_checksum) # chunk_ctx.inputchunk_checksum has the correct checksum, but there is no valid conversion # (because it is unsafe). # Use a macro to do it chunk_ctx.get_inputchunk = macro( {"inputchunk_checksum": { "io": "input", "celltype": "checksum" }}) get_inputchunk = lib_module_dict["helper"]["get_inputchunk_dict"] chunk_ctx.get_inputchunk.code.cell().set(get_inputchunk) chunk_ctx.inputchunk_checksum.connect( chunk_ctx.get_inputchunk.inputchunk_checksum) p = path(chunk_ctx.get_inputchunk.ctx).inputchunk chunk_ctx.inputchunk = cell("mixed", hash_pattern={"*": "#"}) p.connect(chunk_ctx.inputchunk) if first: if not hasattr(hc, "result"): raise TypeError( "map_dict_chunk context must have a cell called 'result'") if isinstance(hc.result, StructuredCell): raise TypeError( "map_dict_chunk context has a cell called 'result', but its celltype must be mixed, not structured" ) if not isinstance(hc.result, CoreCell): raise TypeError( "map_dict_chunk context must have an attribute 'result' that is a cell, not a {}" .format(type(hc.result))) chunk_ctx.inputchunk.connect(hci) chunk_ctx.result = cell("mixed", hash_pattern={"*": "#"}) chunk_ctx.result_deep = cell("checksum") hc.result.connect(chunk_ctx.result) chunk_ctx.result.connect(chunk_ctx.result_deep) chunk_ctx.result_deep.connect(ctx.sc.inchannels[(n + 1, )]) con = ["ctx", subctx, "result"], ["..result"] pseudo_connections.append(con) first = False ctx.subresults = cell("plain") ctx.sc.outchannels[()].connect(ctx.subresults) merge_subresults = lib_module_dict["helper"]["merge_subresults_chunk"] ctx.merge_subresults = transformer({ "subresults": { "io": "input", "celltype": "plain" }, "result": { "io": "output", "celltype": "plain" } }) ctx.merge_subresults.code.cell().set(merge_subresults) ctx.subresults.connect(ctx.merge_subresults.subresults) ctx.result_deep = cell("plain") ctx.merge_subresults.result.connect(ctx.result_deep) # ctx.result_deep has the correct checksum, but there is no valid conversion # (because it is unsafe). # Use a macro to do it ctx.get_result = macro( {"result_checksum": { "io": "input", "celltype": "checksum" }}) get_result = lib_module_dict["helper"]["get_result_dict"] ctx.get_result.code.cell().set(get_result) ctx.result_deep.connect(ctx.get_result.result_checksum) p = path(ctx.get_result.ctx).result ctx.result = cell("mixed", hash_pattern={"*": "#"}) p.connect(ctx.result) if not elision: ctx._pseudo_connections = pseudo_connections
ctx.macro_code.connect(ctx.macro.code) ctx.tfx = transformer({"x0": "input", "x": "output"}) ctx.tfx.code.cell().set("x = x0 + '!'") ctx.tfx_x0 = cell("text") ctx.tfx_x0.connect(ctx.tfx.x0) ctx.macro.ctx.x0.connect(ctx.tfx_x0) ctx.x = cell("text") ctx.tfxx = cell("text") ctx.tfx.x.connect(ctx.tfxx) ctx.tfxx.connect(ctx.macro.ctx.x_unilink) ctx.tfx.x.connect(ctx.x) ctx.y = cell("text") ctx.macro.ctx.y.connect(ctx.y) ctx.e = cell("plain") ctx.e2 = cell("plain") p_d = path(ctx.macro.ctx).d p_d.connect(ctx.e) p_tf2e = path(ctx.macro.ctx).tf2e p_tf2e2 = path(ctx.macro.ctx).tf2e2 ctx.e.connect(p_tf2e) p_tf2e2.connect(ctx.e2) ctx.z = cell("text").set("z") ctx.z_unilink = unilink(ctx.z) ctx.z_unilink.connect(ctx.macro.ctx.z) ctx.q = cell("text") ctx.macro.ctx.q_unilink.connect(ctx.q) ctx.subq = cell("text") ctx.macro.ctx.q.connect(ctx.subq) ctx.subq.connect(ctx.macro.ctx.qq) ctx.r = cell("text") ctx.r_unilink = unilink(ctx.r)
"x": "output" }) ctx.tfx.code.cell().set("x = x0 + '!'") ctx.tfx_x0 = cell("text") ctx.tfx_x0.connect(ctx.tfx.x0) ctx.macro.ctx.x0.connect(ctx.tfx_x0) ctx.x = cell("text") ctx.tfxx = cell("text") ctx.tfx.x.connect(ctx.tfxx) ctx.tfxx.connect(ctx.macro.ctx.x_link) ctx.tfx.x.connect(ctx.x) ctx.y = cell("text") ctx.macro.ctx.y.connect(ctx.y) ctx.e = cell("plain") ctx.e2 = cell("plain") p_d = path(ctx.macro.ctx).d p_d.connect(ctx.e) p_tf2e = path(ctx.macro.ctx).tf2e p_tf2e2 = path(ctx.macro.ctx).tf2e2 ctx.e.connect(p_tf2e) p_tf2e2.connect(ctx.e2) ctx.z = cell("text").set("z") ctx.z_link = link(ctx.z) ctx.z_link.connect(ctx.macro.ctx.z) ctx.q = cell("text") ctx.macro.ctx.q_link.connect(ctx.q) ctx.subq = cell("text") ctx.macro.ctx.q.connect(ctx.subq) ctx.subq.connect(ctx.macro.ctx.qq) ctx.r = cell("text") ctx.r_link = link(ctx.r)
def map_list_N_nested(ctx, elision_chunksize, inp_prefix, graph, inp, *, map_list_N_nested_code, macro_code_lib_code, macro_code_lib0=None): global macro_code_lib if macro_code_lib0 is not None: macro_code_lib = macro_code_lib0 from seamless.core import cell, macro, context, path, transformer first_k = list(inp.keys())[0] length = len(inp[first_k]) print("NEST", length, inp[first_k][0]) first_k = first_k[len(inp_prefix):] for k0 in inp: k = k0[len(inp_prefix):] if len(inp[k0]) != length: err = "all cells in inp must have the same length, but '{}' has length {} while '{}' has length {}" raise ValueError(err.format(k, len(inp[k0]), first_k, length)) if length > elision_chunksize: merge_subresults = """def merge_subresults(**subresults): result = [] for k in sorted(subresults.keys()): v = subresults[k] result += v return result""" ctx.macro_code = cell("python").set(map_list_N_nested_code) ctx.macro_code_lib_code = cell("plain").set(macro_code_lib_code) ctx.macro_code_lib = cell("plain").set({ "type": "interpreted", "language": "python", "code": macro_code_lib_code }) ctx.graph = cell("plain").set(graph) ctx.inp_prefix = cell("str").set(inp_prefix) ctx.elision_chunksize = cell("int").set(elision_chunksize) chunk_index = 0 macro_params = { 'inp_prefix': { 'celltype': 'str' }, 'elision_chunksize': { 'celltype': 'int' }, 'graph': { 'celltype': 'plain' }, 'inp': { 'celltype': 'plain' }, "map_list_N_nested_code": { 'celltype': 'python' }, "macro_code_lib": { 'celltype': 'plain', 'subcelltype': 'module' }, "macro_code_lib_code": { 'celltype': 'plain' }, } subresults = {} chunksize = elision_chunksize while chunksize * elision_chunksize < length: chunksize *= elision_chunksize for n in range(0, length, chunksize): chunk_inp = {} for k in inp: chunk_inp[k] = inp[k][n:n + chunksize] chunk_index += 1 subresult = cell("checksum") """ # The following will work, but make it un-elidable setattr(ctx, "chunk_%d" % chunk_index, context()) chunk_ctx = getattr(ctx, "chunk_%d" % chunk_index) macro_code_lib.map_list_N(chunk_ctx, inp_prefix, graph, chunk_inp) # """ m = macro(macro_params) elision = {"macro": m, "input_cells": {}, "output_cells": {}} m.allow_elision = True setattr(ctx, "m{}".format(chunk_index), m) ctx.macro_code.connect(m.code) ctx.inp_prefix.connect(m.inp_prefix) ctx.elision_chunksize.connect(m.elision_chunksize) ctx.graph.connect(m.graph) ctx.macro_code.connect(m.map_list_N_nested_code) ctx.macro_code_lib.connect(m.macro_code_lib) ctx.macro_code_lib_code.connect(m.macro_code_lib_code) m.inp.cell().set(chunk_inp) subr = "subresult{}".format(chunk_index) setattr(ctx, subr, subresult) subresults[subr] = subresult result_path = path(m.ctx).result result_path.connect(subresult) elision["output_cells"][subresult] = result_path ctx._get_manager().set_elision(**elision) transformer_params = {} for subr in subresults: transformer_params[subr] = {"io": "input", "celltype": "checksum"} transformer_params["result"] = {"io": "output", "celltype": "checksum"} ctx.merge_subresults = transformer(transformer_params) ctx.merge_subresults.code.cell().set(merge_subresults) tf = ctx.merge_subresults for subr, c in subresults.items(): c.connect(getattr(tf, subr)) ctx.all_subresults = cell("plain") tf.result.connect(ctx.all_subresults) # ctx.all_subresults has the correct checksum, but there is no valid conversion # (because it is unsafe). # Use a macro to do it ctx.get_result = macro( {"result_checksum": { "io": "input", "celltype": "checksum" }}) get_result = """def get_result(ctx, result_checksum): ctx.result = cell("mixed", hash_pattern={"!": "#"}) ctx.result.set_checksum(result_checksum)""" ctx.get_result.code.cell().set(get_result) ctx.all_subresults.connect(ctx.get_result.result_checksum) p = path(ctx.get_result.ctx).result ctx.result = cell("mixed", hash_pattern={"!": "#"}) p.connect(ctx.result) else: macro_code_lib.map_list_N(ctx, inp_prefix, graph, inp) return ctx