From 43e161f717c47f658916621415cb6a438b553364 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 14 Jun 2020 21:13:06 -0400 Subject: [PATCH 01/27] tests/control: Add CUDA variants of ocm_{before,after} tests Signed-off-by: Jan Vesely --- tests/composition/test_control.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/composition/test_control.py b/tests/composition/test_control.py index 38514c99d12..766e9d24e4c 100644 --- a/tests/composition/test_control.py +++ b/tests/composition/test_control.py @@ -1618,7 +1618,10 @@ def test_stateful_mechanism_in_simulation(self): @pytest.mark.parametrize("mode", ['Python', pytest.param('LLVM', marks=pytest.mark.llvm), pytest.param('LLVMExec', marks=pytest.mark.llvm), - pytest.param('LLVMRun', marks=pytest.mark.llvm)]) + pytest.param('LLVMRun', marks=pytest.mark.llvm), + pytest.param('PTX', marks=[pytest.mark.llvm, pytest.mark.cuda]), + pytest.param('PTXExec', marks=[pytest.mark.llvm, pytest.mark.cuda]), + pytest.param('PTXRun', marks=[pytest.mark.llvm, pytest.mark.cuda])]) def test_model_based_ocm_after(self, benchmark, mode): A = pnl.ProcessingMechanism(name='A') @@ -1658,7 +1661,10 @@ def test_model_based_ocm_after(self, benchmark, mode): @pytest.mark.parametrize("mode", ['Python', pytest.param('LLVM', marks=pytest.mark.llvm), pytest.param('LLVMExec', marks=pytest.mark.llvm), - pytest.param('LLVMRun', marks=pytest.mark.llvm)]) + pytest.param('LLVMRun', marks=pytest.mark.llvm), + pytest.param('PTX', marks=[pytest.mark.llvm, pytest.mark.cuda]), + pytest.param('PTXExec', marks=[pytest.mark.llvm, pytest.mark.cuda]), + pytest.param('PTXRun', marks=[pytest.mark.llvm, pytest.mark.cuda])]) def test_model_based_ocm_before(self, benchmark, mode): A = pnl.ProcessingMechanism(name='A') From d12a19d91ac85d8621d9c305a9e00122048bfde8 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Mon, 15 Jun 2020 00:45:17 -0400 Subject: [PATCH 02/27] llvm/cuda: Refactor GPU kernel generation This will make it easier to add more variants in the future Signed-off-by: Jan Vesely --- psyneulink/core/llvm/builder_context.py | 31 ++++++++++++++----------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/psyneulink/core/llvm/builder_context.py b/psyneulink/core/llvm/builder_context.py index dc07446d474..6a1f9c72062 100644 --- a/psyneulink/core/llvm/builder_context.py +++ b/psyneulink/core/llvm/builder_context.py @@ -336,27 +336,30 @@ def _gen_cuda_kernel_wrapper_module(function): global_id = builder.mul(builder.call(ctaid_x_f, []), builder.call(ntid_x_f, [])) global_id = builder.add(global_id, builder.call(tid_x_f, [])) + # Index all pointer arguments + args = kernel_func.args + indexed_args = [] + # Runs need special handling. data_in and data_out are one dimensional, # but hold entries for all parallel invocations. - is_comp_run = len(kernel_func.args) == 7 + is_comp_run = len(args) == 7 if is_comp_run: - runs_count = kernel_func.args[5] - input_count = kernel_func.args[6] + runs_count = args[5] + input_count = args[6] - # Index all pointer arguments - indexed_args = [] - for i, arg in enumerate(kernel_func.args): + for i, arg in enumerate(args): # Don't adjust #inputs and #trials if isinstance(arg.type, ir.PointerType): offset = global_id - # #runs and #trials needs to be the same - if is_comp_run and i >= 5: - offset = ir.IntType(32)(0) - # data arrays need special handling - elif is_comp_run and i == 4: # data_out - offset = builder.mul(global_id, builder.load(runs_count)) - elif is_comp_run and i == 3: # data_in - offset = builder.mul(global_id, builder.load(input_count)) + if is_comp_run: + # #runs and #trials needs to be the same + if i >= 5: + offset = ir.IntType(32)(0) + # data arrays need special handling + elif is_comp_run and i == 4: # data_out + offset = builder.mul(global_id, builder.load(runs_count)) + elif is_comp_run and i == 3: # data_in + offset = builder.mul(global_id, builder.load(input_count)) arg = builder.gep(arg, [offset]) From ecf9dfbdac16fc747f32b83b82284cecb63f2058 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Mon, 15 Jun 2020 04:20:17 -0400 Subject: [PATCH 03/27] llvm/cuda: Add number of threads to cuda_wrap_call invocation Signed-off-by: Jan Vesely --- psyneulink/core/llvm/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/psyneulink/core/llvm/__init__.py b/psyneulink/core/llvm/__init__.py index dac93d76e99..1fe20b03cc8 100644 --- a/psyneulink/core/llvm/__init__.py +++ b/psyneulink/core/llvm/__init__.py @@ -91,9 +91,9 @@ def _cuda_kernel(self): def cuda_call(self, *args, threads=1): self._cuda_kernel(*args, block=(1, 1, 1), grid=(threads, 1)) - def cuda_wrap_call(self, *args): + def cuda_wrap_call(self, *args, threads=1): wrap_args = (jit_engine.pycuda.driver.InOut(a) if isinstance(a, np.ndarray) else a for a in args) - self.cuda_call(*wrap_args) + self.cuda_call(*wrap_args, threads) @staticmethod @functools.lru_cache(maxsize=32) From 75173f9ddd7e9629fa077221033b9af2a097ef83 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Mon, 15 Jun 2020 04:24:59 -0400 Subject: [PATCH 04/27] llvm/cuda: Add support for invoking parallel OCM simulations Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 21 +++++++--- .../control/optimizationcontrolmechanism.py | 5 ++- psyneulink/core/llvm/builder_context.py | 15 ++++++- psyneulink/core/llvm/execution.py | 41 +++++++++++++++++++ tests/composition/test_control.py | 12 +++++- 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 2cdae94fe81..e660a4d7924 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1588,6 +1588,11 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, builder.store(builder.load(min_value_ptr), out_value_ptr) return builder + def _run_cuda_grid(self, ocm, variable, context): + assert ocm is ocm.agent_rep.controller + comp_exec = pnlvm.execution.CompExecution(ocm.agent_rep, [context.execution_id]) + return comp_exec.cuda_evaluate(variable, self.search_space) + def _function(self, variable=None, context=None, @@ -1712,11 +1717,17 @@ def _function(self, "PROGRAM ERROR: bad value for {} arg of {}: {}, {}". \ format(repr(DIRECTION), self.name, direction) - last_sample, last_value, all_samples, all_values = super()._function( - variable=variable, - context=context, - params=params, - ) + + ocm = self.objective_function.__self__ if self._is_composition_optimize() else None + if ocm is not None and \ + ocm.parameters.comp_execution_mode._get(context).startswith("PTX"): + all_samples, all_values = self._run_cuda_grid(ocm, variable, context) + else: + last_sample, last_value, all_samples, all_values = super()._function( + variable=variable, + context=context, + params=params, + ) optimal_value_count = 1 value_sample_pairs = zip(all_values, all_samples) diff --git a/psyneulink/core/components/mechanisms/modulatory/control/optimizationcontrolmechanism.py b/psyneulink/core/components/mechanisms/modulatory/control/optimizationcontrolmechanism.py index 691e589796f..80e81d609e8 100644 --- a/psyneulink/core/components/mechanisms/modulatory/control/optimizationcontrolmechanism.py +++ b/psyneulink/core/components/mechanisms/modulatory/control/optimizationcontrolmechanism.py @@ -983,12 +983,15 @@ def evaluation_function(self, control_allocation, context=None, return_results=F old_composition = context.composition context.composition = self.agent_rep + # We shouldn't get this far if execution mode is not Python + exec_mode = self.parameters.comp_execution_mode._get(context) + assert exec_mode == "Python" result = self.agent_rep.evaluate(self.parameters.feature_values._get(context), control_allocation, self.parameters.num_estimates._get(context), base_context=context, context=new_context, - execution_mode=self.parameters.comp_execution_mode._get(context), + execution_mode=exec_mode, return_results=return_results) context.composition = old_composition diff --git a/psyneulink/core/llvm/builder_context.py b/psyneulink/core/llvm/builder_context.py index 6a1f9c72062..75b635f6cab 100644 --- a/psyneulink/core/llvm/builder_context.py +++ b/psyneulink/core/llvm/builder_context.py @@ -337,9 +337,18 @@ def _gen_cuda_kernel_wrapper_module(function): global_id = builder.add(global_id, builder.call(tid_x_f, [])) # Index all pointer arguments - args = kernel_func.args + args = list(kernel_func.args) indexed_args = [] + is_grid_evaluate = len(args) == 8 + if is_grid_evaluate: + # There are 8 arguments to evaluate: + # param, state, allocations, output, input, comp_state, comp_param, comp_data + # state (#1) needs to be copied, compoition state and data are copied in evaluate + private_state = builder.alloca(args[0].type.pointee) + builder.store(builder.load(args[0]), private_state) + args[0] = private_state + # Runs need special handling. data_in and data_out are one dimensional, # but hold entries for all parallel invocations. is_comp_run = len(args) == 7 @@ -360,6 +369,10 @@ def _gen_cuda_kernel_wrapper_module(function): offset = builder.mul(global_id, builder.load(runs_count)) elif is_comp_run and i == 3: # data_in offset = builder.mul(global_id, builder.load(input_count)) + elif is_grid_evaluate: + # all but #2 and #3 are shared + if i != 2 and i != 3: + offset = ir.IntType(32)(0) arg = builder.gep(arg, [offset]) diff --git a/psyneulink/core/llvm/execution.py b/psyneulink/core/llvm/execution.py index a471e7cfa46..5e1e7782d5d 100644 --- a/psyneulink/core/llvm/execution.py +++ b/psyneulink/core/llvm/execution.py @@ -619,3 +619,44 @@ def cuda_run(self, inputs, runs, num_input_sets): # Copy the data struct from the device ct_out = self.download_ctype(data_out, output_type, 'result') return _convert_ctype_to_python(ct_out) + + def cuda_evaluate(self, variable, search_space): + ocm = self._composition.controller + assert len(self._execution_contexts) == 1 + context = self._execution_contexts[0] + import itertools + + bin_func = pnlvm.LLVMBinaryFunction.from_obj(ocm, tags=frozenset({"evaluate"})) + self.__bin_func = bin_func + assert len(bin_func.byref_arg_types) == 8 + + # There are 8 arguments to evaluate: + # param, state, allocations, results, output, input, comp_params, comp_state, comp_data + # all but #2 and #3 are shared _gen_llvm_evaluate_function + ct_param = bin_func.byref_arg_types[0](*ocm._get_evaluate_param_initializer(context)) + ct_state = bin_func.byref_arg_types[1](*ocm._get_evaluate_state_initializer(context)) + # FIXME: Make sure the dtype matches _gen_llvm_evaluate_function + allocations = np.atleast_2d([*itertools.product(*search_space)]) + ct_allocations = allocations.ctypes.data_as(ctypes.POINTER(bin_func.byref_arg_types[2] * len(allocations))) + out_ty = bin_func.byref_arg_types[3] * len(allocations) + ct_in = variable.ctypes.data_as(ctypes.POINTER(bin_func.byref_arg_types[4])) + + ct_comp_param = bin_func.byref_arg_types[5](*ocm.agent_rep._get_param_initializer(context)) + ct_comp_state = bin_func.byref_arg_types[6](*ocm.agent_rep._get_state_initializer(context)) + ct_comp_data = bin_func.byref_arg_types[7](*ocm.agent_rep._get_data_initializer(context)) + + cuda_args = (self.upload_ctype(ct_param, 'params'), + self.upload_ctype(ct_state, 'state'), + self.upload_ctype(ct_allocations.contents, 'input'), + jit_engine.pycuda.driver.mem_alloc(ctypes.sizeof(out_ty)), + self.upload_ctype(ct_in.contents, 'input'), + self.upload_ctype(ct_comp_param, 'params'), + self.upload_ctype(ct_comp_state, 'state'), + self.upload_ctype(ct_comp_data, 'data'), + ) + + bin_func.cuda_call(*cuda_args, threads=len(allocations)) + ct_res = self.download_ctype(cuda_args[3], out_ty, 'result') + results = _convert_ctype_to_python(ct_res) + + return allocations, results diff --git a/tests/composition/test_control.py b/tests/composition/test_control.py index 766e9d24e4c..230c5d3d96b 100644 --- a/tests/composition/test_control.py +++ b/tests/composition/test_control.py @@ -1616,6 +1616,7 @@ def test_stateful_mechanism_in_simulation(self): @pytest.mark.composition @pytest.mark.benchmark(group="Model Based OCM") @pytest.mark.parametrize("mode", ['Python', + pytest.param('Python-PTX', marks=[pytest.mark.llvm, pytest.mark.cuda]), pytest.param('LLVM', marks=pytest.mark.llvm), pytest.param('LLVMExec', marks=pytest.mark.llvm), pytest.param('LLVMRun', marks=pytest.mark.llvm), @@ -1623,6 +1624,8 @@ def test_stateful_mechanism_in_simulation(self): pytest.param('PTXExec', marks=[pytest.mark.llvm, pytest.mark.cuda]), pytest.param('PTXRun', marks=[pytest.mark.llvm, pytest.mark.cuda])]) def test_model_based_ocm_after(self, benchmark, mode): + # OCM default mode is Python + mode, ocm_mode = (mode + "-Python").split('-')[0:2] A = pnl.ProcessingMechanism(name='A') B = pnl.ProcessingMechanism(name='B') @@ -1642,7 +1645,8 @@ def test_model_based_ocm_after(self, benchmark, mode): features=[A.input_port], objective_mechanism=objective_mech, function=pnl.GridSearch(), - control_signals=[control_signal]) + control_signals=[control_signal], + comp_execution_mode=ocm_mode) # objective_mech.log.set_log_conditions(pnl.OUTCOME) comp.add_controller(ocm) @@ -1659,6 +1663,7 @@ def test_model_based_ocm_after(self, benchmark, mode): @pytest.mark.composition @pytest.mark.benchmark(group="Model Based OCM") @pytest.mark.parametrize("mode", ['Python', + pytest.param('Python-PTX', marks=[pytest.mark.llvm, pytest.mark.cuda]), pytest.param('LLVM', marks=pytest.mark.llvm), pytest.param('LLVMExec', marks=pytest.mark.llvm), pytest.param('LLVMRun', marks=pytest.mark.llvm), @@ -1666,6 +1671,8 @@ def test_model_based_ocm_after(self, benchmark, mode): pytest.param('PTXExec', marks=[pytest.mark.llvm, pytest.mark.cuda]), pytest.param('PTXRun', marks=[pytest.mark.llvm, pytest.mark.cuda])]) def test_model_based_ocm_before(self, benchmark, mode): + # OCM default mode is Python + mode, ocm_mode = (mode + "-Python").split('-')[0:2] A = pnl.ProcessingMechanism(name='A') B = pnl.ProcessingMechanism(name='B') @@ -1685,7 +1692,8 @@ def test_model_based_ocm_before(self, benchmark, mode): features=[A.input_port], objective_mechanism=objective_mech, function=pnl.GridSearch(), - control_signals=[control_signal]) + control_signals=[control_signal], + comp_execution_mode=ocm_mode) # objective_mech.log.set_log_conditions(pnl.OUTCOME) comp.add_controller(ocm) From 784f2d828d7de73962f8f7e5c2e02505bb63052b Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sat, 20 Jun 2020 16:19:29 -0400 Subject: [PATCH 05/27] llvm, function/GridSearch: Move minimum selection to a standalone method Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 90 ++++++++++--------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index e660a4d7924..05b00a45436 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1472,6 +1472,52 @@ def _get_output_struct_type(self, ctx): val[0] = [0.0] * len(self.search_space) return ctx.convert_python_struct_to_llvm_ir((val[0], val[1])) + def _gen_llvm_select_min(self, ctx, builder, params, state, min_sample_ptr, sample_ptr, + min_value_ptr, value_ptr, opt_count_ptr): + random_state = pnlvm.helpers.get_state_ptr(builder, self, state, + self.parameters.random_state.name) + select_random_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, + self.parameters.select_randomly_from_optimal_values.name) + + select_random_val = builder.load(select_random_ptr) + select_random = builder.fcmp_ordered("!=", select_random_val, + select_random_val.type(0)) + replace_ptr = builder.alloca(pnlvm.ir.IntType(1)) + + + value = builder.load(value_ptr) + min_value = builder.load(min_value_ptr) + # KDM 8/22/19: nonstateful direction here - OK? + direction = "<" if self.direction == MINIMIZE else ">" + replace = builder.fcmp_unordered(direction, value, min_value) + builder.store(replace, replace_ptr) + + # Python does "is_close" check first. + # This implements reservoir sampling + with builder.if_then(select_random): + close = pnlvm.helpers.is_close(builder, value, min_value) + with builder.if_else(close) as (tb, eb): + with tb: + opt_count = builder.load(opt_count_ptr) + opt_count = builder.fadd(opt_count, opt_count.type(1)) + prob = builder.fdiv(opt_count.type(1), opt_count) + # reuse opt_count location. it will be overwritten later anyway + res_ptr = opt_count_ptr + rand_f = ctx.import_llvm_function("__pnl_builtin_mt_rand_double") + builder.call(rand_f, [random_state, res_ptr]) + res = builder.load(res_ptr) + builder.store(opt_count, opt_count_ptr) + replace = builder.fcmp_ordered("<", res, prob) + builder.store(replace, replace_ptr) + with eb: + # we need to reset the counter if we are replacing with new best value + with builder.if_then(builder.load(replace_ptr)): + builder.store(opt_count_ptr.type.pointee(1), opt_count_ptr) + + with builder.if_then(builder.load(replace_ptr)): + builder.store(builder.load(value_ptr), min_value_ptr) + builder.store(builder.load(sample_ptr), min_sample_ptr) + def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, *, tags:frozenset): ocm = getattr(self.objective_function, '__self__', None) if ocm is not None: @@ -1491,20 +1537,12 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, sample_ptr = builder.alloca(sample_t) value_ptr = builder.alloca(value_t) - random_state = pnlvm.helpers.get_state_ptr(builder, self, state, - self.parameters.random_state.name) obj_state_ptr = pnlvm.helpers.get_state_ptr(builder, self, state, self.parameters.objective_function.name) obj_param_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, self.parameters.objective_function.name) search_space_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, self.parameters.search_space.name) - select_random_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, - self.parameters.select_randomly_from_optimal_values.name) - - select_random_val = builder.load(select_random_ptr) - select_random = builder.fcmp_ordered("!=", select_random_val, - select_random_val.type(0)) opt_count_ptr = builder.alloca(ctx.float_ty) builder.store(opt_count_ptr.type.pointee(0), opt_count_ptr) @@ -1545,39 +1583,9 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, value_ptr] + extra_args) # Check if smaller than current best. - # This will also set 'replace' if min_value is NaN. - value = b.load(value_ptr) - min_value = b.load(min_value_ptr) - # KDM 8/22/19: nonstateful direction here - OK? - direction = "<" if self.direction == MINIMIZE else ">" - replace = b.fcmp_unordered(direction, value, min_value) - b.store(replace, replace_ptr) - - # Python does "is_close" check first. - # This implements reservoir sampling - with b.if_then(select_random): - close = pnlvm.helpers.is_close(b, value, min_value) - with b.if_else(close) as (tb, eb): - with tb: - opt_count = b.load(opt_count_ptr) - opt_count = b.fadd(opt_count, opt_count.type(1)) - prob = b.fdiv(opt_count.type(1), opt_count) - # reuse opt_count location. it will be overwritten later anyway - res_ptr = opt_count_ptr - rand_f = ctx.import_llvm_function("__pnl_builtin_mt_rand_double") - b.call(rand_f, [random_state, res_ptr]) - res = b.load(res_ptr) - b.store(opt_count, opt_count_ptr) - replace = b.fcmp_ordered("<", res, prob) - b.store(replace, replace_ptr) - with eb: - # we need to reset the counter if we are replacing with new best value - with b.if_then(b.load(replace_ptr)): - b.store(opt_count_ptr.type.pointee(1), opt_count_ptr) - - with b.if_then(b.load(replace_ptr)): - b.store(b.load(value_ptr), min_value_ptr) - b.store(b.load(sample_ptr), min_sample_ptr) + self._gen_llvm_select_min(ctx, b, params, state, min_sample_ptr, + sample_ptr, min_value_ptr, value_ptr, + opt_count_ptr) builder = b From 53ab49f6693c898be7f806569129118f65fe7da1 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sat, 20 Jun 2020 17:13:44 -0400 Subject: [PATCH 06/27] llvm, functions/GridSearch: Refactor searching for minimum Remove location reuse hack Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 05b00a45436..0ac76a8c222 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1482,13 +1482,17 @@ def _gen_llvm_select_min(self, ctx, builder, params, state, min_sample_ptr, samp select_random_val = builder.load(select_random_ptr) select_random = builder.fcmp_ordered("!=", select_random_val, select_random_val.type(0)) - replace_ptr = builder.alloca(pnlvm.ir.IntType(1)) + rand_out_ptr = builder.alloca(ctx.float_ty) - value = builder.load(value_ptr) - min_value = builder.load(min_value_ptr) # KDM 8/22/19: nonstateful direction here - OK? direction = "<" if self.direction == MINIMIZE else ">" + replace_ptr = builder.alloca(pnlvm.ir.IntType(1)) + + # Check the value against current min + value = builder.load(value_ptr) + min_value = builder.load(min_value_ptr) + replace = builder.fcmp_unordered(direction, value, min_value) builder.store(replace, replace_ptr) @@ -1500,17 +1504,17 @@ def _gen_llvm_select_min(self, ctx, builder, params, state, min_sample_ptr, samp with tb: opt_count = builder.load(opt_count_ptr) opt_count = builder.fadd(opt_count, opt_count.type(1)) + builder.store(opt_count, opt_count_ptr) + + # Roll a dice to see if we should replace the current min prob = builder.fdiv(opt_count.type(1), opt_count) - # reuse opt_count location. it will be overwritten later anyway - res_ptr = opt_count_ptr rand_f = ctx.import_llvm_function("__pnl_builtin_mt_rand_double") - builder.call(rand_f, [random_state, res_ptr]) - res = builder.load(res_ptr) - builder.store(opt_count, opt_count_ptr) - replace = builder.fcmp_ordered("<", res, prob) + builder.call(rand_f, [random_state, rand_out_ptr]) + rand_out = builder.load(rand_out_ptr) + replace = builder.fcmp_ordered("<", rand_out, prob) builder.store(replace, replace_ptr) with eb: - # we need to reset the counter if we are replacing with new best value + # Reset the counter if we are replacing with new best value with builder.if_then(builder.load(replace_ptr)): builder.store(opt_count_ptr.type.pointee(1), opt_count_ptr) From 37267db22c553c1446baf54f27409c72fd43ca97 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sat, 20 Jun 2020 23:40:50 -0400 Subject: [PATCH 07/27] llvm, component: Codestyle Signed-off-by: Jan Vesely --- psyneulink/core/components/component.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/psyneulink/core/components/component.py b/psyneulink/core/components/component.py index 129dfdd6796..a88249a6be5 100644 --- a/psyneulink/core/components/component.py +++ b/psyneulink/core/components/component.py @@ -1396,10 +1396,8 @@ def _gen_llvm_function(self, *, ctx:pnlvm.LLVMBuilderContext, p.attributes.add('noalias') if "reset" in tags: - builder = self._gen_llvm_function_reset(ctx, builder, - params, state, - arg_in, arg_out, - tags=tags) + builder = self._gen_llvm_function_reset(ctx, builder, params, state, + arg_in, arg_out, tags=tags) else: builder = self._gen_llvm_function_body(ctx, builder, params, state, arg_in, arg_out, tags=tags) From 1107d790a22b8ebd78af09de1cd0b08b896eac0a Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 21 Jun 2020 02:08:07 -0400 Subject: [PATCH 08/27] llvm, function/GridSearch: Export select_min as a separate function Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 0ac76a8c222..7650c0a8e45 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1345,14 +1345,16 @@ def reset_grid(self): self.grid = itertools.product(*[s for s in self.search_space]) def _gen_llvm_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:frozenset): - try: + if "select_min" in tags: + return self._gen_llvm_select_min_function(ctx=ctx, tags=tags) + if self._is_composition_optimize(): # self.objective_function may be bound method of # an OptimizationControlMechanism ocm = self.objective_function.__self__ extra_args = [ctx.get_param_struct_type(ocm.agent_rep).as_pointer(), ctx.get_state_struct_type(ocm.agent_rep).as_pointer(), ctx.get_data_struct_type(ocm.agent_rep).as_pointer()] - except AttributeError: + else: extra_args = [] f = super()._gen_llvm_function(ctx=ctx, extra_args=extra_args, tags=tags) @@ -1387,7 +1389,7 @@ def _get_param_ids(self): return ids - def _get_search_dim(self, ctx, d): + def _get_search_dim_type(self, ctx, d): if isinstance(d.generator, list): # Make sure we only generate float values return ctx.convert_python_struct_to_llvm_ir([float(x) for x in d.generator]) @@ -1397,7 +1399,7 @@ def _get_search_dim(self, ctx, d): def _get_param_struct_type(self, ctx): param_struct = ctx.get_param_struct_type(super()) - search_space = (self._get_search_dim(ctx, d) for d in self.search_space) + search_space = (self._get_search_dim_type(ctx, d) for d in self.search_space) search_space_struct = pnlvm.ir.LiteralStructType(search_space) if self._is_composition_optimize(): @@ -1472,12 +1474,38 @@ def _get_output_struct_type(self, ctx): val[0] = [0.0] * len(self.search_space) return ctx.convert_python_struct_to_llvm_ir((val[0], val[1])) - def _gen_llvm_select_min(self, ctx, builder, params, state, min_sample_ptr, sample_ptr, - min_value_ptr, value_ptr, opt_count_ptr): + def _gen_llvm_select_min_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:frozenset): + assert "select_min" in tags + ocm = getattr(self.objective_function, '__self__', None) + if ocm is not None: + assert ocm.function is self + obj_func = ctx.import_llvm_function(ocm, tags=tags.union({"evaluate"})) + sample_t = ocm._get_evaluate_alloc_struct_type(ctx) + value_t = ocm._get_evaluate_output_struct_type(ctx) + else: + obj_func = ctx.import_llvm_function(self.objective_function) + sample_t = obj_func.args[2].type.pointee + value_t = obj_func.args[3].type.pointee + + args = [ctx.get_param_struct_type(self).as_pointer(), + ctx.get_state_struct_type(self).as_pointer(), + sample_t.as_pointer(), + sample_t.as_pointer(), + value_t.as_pointer(), + value_t.as_pointer(), + ctx.float_ty.as_pointer()] + builder = ctx.create_llvm_function(args, self, tags=tags, + return_type=pnlvm.ir.VoidType()) + + params, state, min_sample_ptr, sample_ptr, min_value_ptr, value_ptr, opt_count_ptr = builder.function.args + for p in builder.function.args: + p.attributes.add('noalias') + p.attributes.add('nonnull') + random_state = pnlvm.helpers.get_state_ptr(builder, self, state, - self.parameters.random_state.name) + self.parameters.random_state.name) select_random_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, - self.parameters.select_randomly_from_optimal_values.name) + self.parameters.select_randomly_from_optimal_values.name) select_random_val = builder.load(select_random_ptr) select_random = builder.fcmp_ordered("!=", select_random_val, @@ -1522,6 +1550,9 @@ def _gen_llvm_select_min(self, ctx, builder, params, state, min_sample_ptr, samp builder.store(builder.load(value_ptr), min_value_ptr) builder.store(builder.load(sample_ptr), min_sample_ptr) + builder.ret_void() + return builder.function + def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, *, tags:frozenset): ocm = getattr(self.objective_function, '__self__', None) if ocm is not None: @@ -1557,6 +1588,8 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, # in the first iteration builder.store(min_value_ptr.type.pointee("NaN"), min_value_ptr) + select_min_f = ctx.import_llvm_function(self, tags=tags.union({"select_min"})) + b = builder with contextlib.ExitStack() as stack: for i in range(len(search_space_ptr.type.pointee)): @@ -1587,9 +1620,8 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, value_ptr] + extra_args) # Check if smaller than current best. - self._gen_llvm_select_min(ctx, b, params, state, min_sample_ptr, - sample_ptr, min_value_ptr, value_ptr, - opt_count_ptr) + b.call(select_min_f, [params, state, min_sample_ptr, sample_ptr, + min_value_ptr, value_ptr, opt_count_ptr]) builder = b From fa105ca9b3cbec6f3c8282d1393f3612b9f3f068 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Mon, 22 Jun 2020 22:33:36 -0400 Subject: [PATCH 09/27] llvm, tests: Add readable ids to printf tests Signed-off-by: Jan Vesely --- tests/llvm/test_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/llvm/test_helpers.py b/tests/llvm/test_helpers.py index 03d05c4f863..9d6b6069968 100644 --- a/tests/llvm/test_helpers.py +++ b/tests/llvm/test_helpers.py @@ -196,7 +196,7 @@ def test_helper_all_close(mode): (pnlvm.ir.IntType(32), "%u", range(0, 100)), (pnlvm.ir.IntType(64), "%ld", [int(-4E10), int(-3E10), int(-2E10)]), (pnlvm.ir.DoubleType(), "%lf", [x *.5 for x in range(0, 10)]), - ]) + ], ids=["i32", "i64", "double"]) @pytest.mark.skipif(sys.platform == 'win32', reason="Loading C library is complicated on windows") def test_helper_printf(capfd, ir_argtype, format_spec, values_to_check): format_str = f"Hello {(format_spec+' ')*len(values_to_check)} \n" From 28fe3d8d136f2e4c09a1de3a9d47fca56b2076b1 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Mon, 22 Jun 2020 23:21:35 -0400 Subject: [PATCH 10/27] llvm/cuda: Pass number of cuda threads as keyword arg It shouldn't be included in 'cuda_call' args. Fixes: ecf9dfbdac16fc747f32b83b82284cecb63f2058 ("llvm/cuda: Add number of threads to cuda_wrap_call invocation") Signed-off-by: Jan Vesely --- psyneulink/core/llvm/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/core/llvm/__init__.py b/psyneulink/core/llvm/__init__.py index 1fe20b03cc8..23db92a5260 100644 --- a/psyneulink/core/llvm/__init__.py +++ b/psyneulink/core/llvm/__init__.py @@ -93,7 +93,7 @@ def cuda_call(self, *args, threads=1): def cuda_wrap_call(self, *args, threads=1): wrap_args = (jit_engine.pycuda.driver.InOut(a) if isinstance(a, np.ndarray) else a for a in args) - self.cuda_call(*wrap_args, threads) + self.cuda_call(*wrap_args, threads=threads) @staticmethod @functools.lru_cache(maxsize=32) From cba75631d356fa9492ca12c1a2ed38e4d7679021 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 00:59:21 -0400 Subject: [PATCH 11/27] llvm, functions/GridSearch: Codestyle Signed-off-by: Jan Vesely --- .../core/components/functions/optimizationfunctions.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 7650c0a8e45..3b979c47bae 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1479,7 +1479,6 @@ def _gen_llvm_select_min_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:fr ocm = getattr(self.objective_function, '__self__', None) if ocm is not None: assert ocm.function is self - obj_func = ctx.import_llvm_function(ocm, tags=tags.union({"evaluate"})) sample_t = ocm._get_evaluate_alloc_struct_type(ctx) value_t = ocm._get_evaluate_output_struct_type(ctx) else: @@ -1573,11 +1572,11 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, value_ptr = builder.alloca(value_t) obj_state_ptr = pnlvm.helpers.get_state_ptr(builder, self, state, - self.parameters.objective_function.name) + self.parameters.objective_function.name) obj_param_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, - self.parameters.objective_function.name) + self.parameters.objective_function.name) search_space_ptr = pnlvm.helpers.get_param_ptr(builder, self, params, - self.parameters.search_space.name) + self.parameters.search_space.name) opt_count_ptr = builder.alloca(ctx.float_ty) builder.store(opt_count_ptr.type.pointee(0), opt_count_ptr) @@ -1588,8 +1587,6 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, # in the first iteration builder.store(min_value_ptr.type.pointee("NaN"), min_value_ptr) - select_min_f = ctx.import_llvm_function(self, tags=tags.union({"select_min"})) - b = builder with contextlib.ExitStack() as stack: for i in range(len(search_space_ptr.type.pointee)): @@ -1620,6 +1617,7 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, value_ptr] + extra_args) # Check if smaller than current best. + select_min_f = ctx.import_llvm_function(self, tags=tags.union({"select_min"})) b.call(select_min_f, [params, state, min_sample_ptr, sample_ptr, min_value_ptr, value_ptr, opt_count_ptr]) From 958b92ee0fb05ca07290c289813bab5a85a6379c Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 13:05:03 -0400 Subject: [PATCH 12/27] llvm/cuda, functions/GridSearch: Return ctype structures instead of converting to list Signed-off-by: Jan Vesely --- .../core/components/functions/optimizationfunctions.py | 4 +++- psyneulink/core/llvm/execution.py | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 3b979c47bae..b10b8a5f724 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1633,7 +1633,9 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, def _run_cuda_grid(self, ocm, variable, context): assert ocm is ocm.agent_rep.controller comp_exec = pnlvm.execution.CompExecution(ocm.agent_rep, [context.execution_id]) - return comp_exec.cuda_evaluate(variable, self.search_space) + ct_alloc, ct_res = comp_exec.cuda_evaluate(variable, self.search_space) + + return ct_alloc, ct_res def _function(self, variable=None, diff --git a/psyneulink/core/llvm/execution.py b/psyneulink/core/llvm/execution.py index 5e1e7782d5d..da7774bb055 100644 --- a/psyneulink/core/llvm/execution.py +++ b/psyneulink/core/llvm/execution.py @@ -656,7 +656,6 @@ def cuda_evaluate(self, variable, search_space): ) bin_func.cuda_call(*cuda_args, threads=len(allocations)) - ct_res = self.download_ctype(cuda_args[3], out_ty, 'result') - results = _convert_ctype_to_python(ct_res) + ct_results = self.download_ctype(cuda_args[3], out_ty, 'result') - return allocations, results + return ct_allocations.contents, ct_results From 9ffcd9f42dd6f6d440d4fface58a8ba686db3ca8 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 14:38:59 -0400 Subject: [PATCH 13/27] llvm, functions/GridSearch: Add count parameter to 'select_min' function This will be used for standalone calls Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 75 ++++++++++--------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index b10b8a5f724..33848e50129 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1492,12 +1492,13 @@ def _gen_llvm_select_min_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:fr sample_t.as_pointer(), value_t.as_pointer(), value_t.as_pointer(), - ctx.float_ty.as_pointer()] + ctx.float_ty.as_pointer(), + ctx.int32_ty] builder = ctx.create_llvm_function(args, self, tags=tags, return_type=pnlvm.ir.VoidType()) - params, state, min_sample_ptr, sample_ptr, min_value_ptr, value_ptr, opt_count_ptr = builder.function.args - for p in builder.function.args: + params, state, min_sample_ptr, samples_ptr, min_value_ptr, values_ptr, opt_count_ptr, count = builder.function.args + for p in builder.function.args[:-1]: p.attributes.add('noalias') p.attributes.add('nonnull') @@ -1517,37 +1518,40 @@ def _gen_llvm_select_min_function(self, *, ctx:pnlvm.LLVMBuilderContext, tags:fr replace_ptr = builder.alloca(pnlvm.ir.IntType(1)) # Check the value against current min - value = builder.load(value_ptr) - min_value = builder.load(min_value_ptr) - - replace = builder.fcmp_unordered(direction, value, min_value) - builder.store(replace, replace_ptr) - - # Python does "is_close" check first. - # This implements reservoir sampling - with builder.if_then(select_random): - close = pnlvm.helpers.is_close(builder, value, min_value) - with builder.if_else(close) as (tb, eb): - with tb: - opt_count = builder.load(opt_count_ptr) - opt_count = builder.fadd(opt_count, opt_count.type(1)) - builder.store(opt_count, opt_count_ptr) - - # Roll a dice to see if we should replace the current min - prob = builder.fdiv(opt_count.type(1), opt_count) - rand_f = ctx.import_llvm_function("__pnl_builtin_mt_rand_double") - builder.call(rand_f, [random_state, rand_out_ptr]) - rand_out = builder.load(rand_out_ptr) - replace = builder.fcmp_ordered("<", rand_out, prob) - builder.store(replace, replace_ptr) - with eb: - # Reset the counter if we are replacing with new best value - with builder.if_then(builder.load(replace_ptr)): - builder.store(opt_count_ptr.type.pointee(1), opt_count_ptr) - - with builder.if_then(builder.load(replace_ptr)): - builder.store(builder.load(value_ptr), min_value_ptr) - builder.store(builder.load(sample_ptr), min_sample_ptr) + with pnlvm.helpers.for_loop_zero_inc(builder, count, "compare_loop") as (b, idx): + value_ptr = b.gep(values_ptr, [idx]) + sample_ptr = b.gep(samples_ptr, [idx]) + value = b.load(value_ptr) + min_value = b.load(min_value_ptr) + + replace = b.fcmp_unordered(direction, value, min_value) + b.store(replace, replace_ptr) + + # Python does "is_close" check first. + # This implements reservoir sampling + with b.if_then(select_random): + close = pnlvm.helpers.is_close(b, value, min_value) + with b.if_else(close) as (tb, eb): + with tb: + opt_count = b.load(opt_count_ptr) + opt_count = b.fadd(opt_count, opt_count.type(1)) + b.store(opt_count, opt_count_ptr) + + # Roll a dice to see if we should replace the current min + prob = b.fdiv(opt_count.type(1), opt_count) + rand_f = ctx.import_llvm_function("__pnl_builtin_mt_rand_double") + b.call(rand_f, [random_state, rand_out_ptr]) + rand_out = b.load(rand_out_ptr) + replace = b.fcmp_ordered("<", rand_out, prob) + b.store(replace, replace_ptr) + with eb: + # Reset the counter if we are replacing with new best value + with b.if_then(b.load(replace_ptr)): + b.store(opt_count_ptr.type.pointee(1), opt_count_ptr) + + with b.if_then(b.load(replace_ptr)): + b.store(b.load(value_ptr), min_value_ptr) + b.store(b.load(sample_ptr), min_sample_ptr) builder.ret_void() return builder.function @@ -1619,7 +1623,8 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, # Check if smaller than current best. select_min_f = ctx.import_llvm_function(self, tags=tags.union({"select_min"})) b.call(select_min_f, [params, state, min_sample_ptr, sample_ptr, - min_value_ptr, value_ptr, opt_count_ptr]) + min_value_ptr, value_ptr, opt_count_ptr, + ctx.int32_ty(1)]) builder = b From 1dc179590e05c055a005ea4b27f2e09fbb3afec5 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 14:40:41 -0400 Subject: [PATCH 14/27] llvm: Drop leftover debug note Signed-off-by: Jan Vesely --- psyneulink/core/llvm/execution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/core/llvm/execution.py b/psyneulink/core/llvm/execution.py index da7774bb055..a55f2ff65f6 100644 --- a/psyneulink/core/llvm/execution.py +++ b/psyneulink/core/llvm/execution.py @@ -632,7 +632,7 @@ def cuda_evaluate(self, variable, search_space): # There are 8 arguments to evaluate: # param, state, allocations, results, output, input, comp_params, comp_state, comp_data - # all but #2 and #3 are shared _gen_llvm_evaluate_function + # all but #2 and #3 are shared ct_param = bin_func.byref_arg_types[0](*ocm._get_evaluate_param_initializer(context)) ct_state = bin_func.byref_arg_types[1](*ocm._get_evaluate_state_initializer(context)) # FIXME: Make sure the dtype matches _gen_llvm_evaluate_function From c8589aa916ff944328ae95f8cadd965b699d3209 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 16:18:10 -0400 Subject: [PATCH 15/27] llvm/cuda, functions/GridSearch: Use CPU compiled version to combine simulation results Signed-off-by: Jan Vesely --- .../functions/optimizationfunctions.py | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 33848e50129..7a2f22327d8 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1637,10 +1637,26 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, def _run_cuda_grid(self, ocm, variable, context): assert ocm is ocm.agent_rep.controller + # Map allocations to values comp_exec = pnlvm.execution.CompExecution(ocm.agent_rep, [context.execution_id]) - ct_alloc, ct_res = comp_exec.cuda_evaluate(variable, self.search_space) + ct_alloc, ct_values = comp_exec.cuda_evaluate(variable, self.search_space) - return ct_alloc, ct_res + # Reduce array of values to min/max + # select_min params are: + # params, state, min_sample_ptr, sample_ptr, min_value_ptr, value_ptr, opt_count_ptr, count + bin_func = pnlvm.LLVMBinaryFunction.from_obj(self, tags=frozenset({"select_min"})) + ct_param = bin_func.byref_arg_types[0](*self._get_param_initializer(context)) + ct_state = bin_func.byref_arg_types[1](*self._get_state_initializer(context)) + ct_opt_sample = bin_func.byref_arg_types[2](float("NaN")) + ct_opt_value = bin_func.byref_arg_types[4]() + ct_opt_count = bin_func.byref_arg_types[6](0) + assert len(ct_values) == len(ct_alloc) + ct_count = bin_func.c_func.argtypes[7](len(ct_alloc)) + + bin_func(ct_param, ct_state, ct_opt_sample, ct_alloc, ct_opt_value, + ct_values, ct_opt_count, ct_count) + + return ct_opt_sample, ct_opt_value, ct_alloc, ct_values def _function(self, variable=None, @@ -1770,7 +1786,9 @@ def _function(self, ocm = self.objective_function.__self__ if self._is_composition_optimize() else None if ocm is not None and \ ocm.parameters.comp_execution_mode._get(context).startswith("PTX"): - all_samples, all_values = self._run_cuda_grid(ocm, variable, context) + opt_sample, opt_value, all_samples, all_values = self._run_cuda_grid(ocm, variable, context) + value_optimal = opt_value + sample_optimal = opt_sample else: last_sample, last_value, all_samples, all_values = super()._function( variable=variable, @@ -1778,28 +1796,28 @@ def _function(self, params=params, ) - optimal_value_count = 1 - value_sample_pairs = zip(all_values, all_samples) - value_optimal, sample_optimal = next(value_sample_pairs) + optimal_value_count = 1 + value_sample_pairs = zip(all_values, all_samples) + value_optimal, sample_optimal = next(value_sample_pairs) - select_randomly = self.parameters.select_randomly_from_optimal_values._get(context) - for value, sample in value_sample_pairs: - if select_randomly and np.allclose(value, value_optimal): - optimal_value_count += 1 + select_randomly = self.parameters.select_randomly_from_optimal_values._get(context) + for value, sample in value_sample_pairs: + if select_randomly and np.allclose(value, value_optimal): + optimal_value_count += 1 - # swap with probability = 1/optimal_value_count in order to achieve - # uniformly random selection from identical outcomes - probability = 1 / optimal_value_count - random_state = self._get_current_function_param("random_state", context) - random_value = random_state.rand() + # swap with probability = 1/optimal_value_count in order to achieve + # uniformly random selection from identical outcomes + probability = 1 / optimal_value_count + random_state = self._get_current_function_param("random_state", context) + random_value = random_state.rand() - if random_value < probability: - value_optimal, sample_optimal = value, sample + if random_value < probability: + value_optimal, sample_optimal = value, sample - elif (value > value_optimal and direction == MAXIMIZE) or \ - (value < value_optimal and direction == MINIMIZE): - value_optimal, sample_optimal = value, sample - optimal_value_count = 1 + elif (value > value_optimal and direction == MAXIMIZE) or \ + (value < value_optimal and direction == MINIMIZE): + value_optimal, sample_optimal = value, sample + optimal_value_count = 1 if self._return_samples: return_all_samples = all_samples From f468367e0930cd352be52f313d16e4780562204d Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Tue, 23 Jun 2020 18:18:35 -0400 Subject: [PATCH 16/27] tests/predator-prey: Add Python-PTX variant Signed-off-by: Jan Vesely --- tests/models/test_greedy_agent.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/models/test_greedy_agent.py b/tests/models/test_greedy_agent.py index 39fe8f1b16b..e292ed29ceb 100644 --- a/tests/models/test_greedy_agent.py +++ b/tests/models/test_greedy_agent.py @@ -120,6 +120,7 @@ def test_simplified_greedy_agent_random(benchmark, mode): @pytest.mark.model @pytest.mark.benchmark(group="Predator Prey") @pytest.mark.parametrize("mode", ['Python', + pytest.param('Python-PTX', marks=[pytest.mark.llvm, pytest.mark.cuda]), pytest.param('LLVM', marks=[pytest.mark.llvm]), pytest.param('LLVMExec', marks=[pytest.mark.llvm]), pytest.param('LLVMRun', marks=[pytest.mark.llvm]), @@ -130,8 +131,10 @@ def test_simplified_greedy_agent_random(benchmark, mode): @pytest.mark.parametrize("samples", [[0,10], pytest.param([0,3,6,10], marks=pytest.mark.stress), pytest.param([0,2,4,6,8,10], marks=pytest.mark.stress), -], ids=['2','4','6']) +], ids=lambda x: len(x)) def test_predator_prey(benchmark, mode, samples): + # OCM default mode is Python + mode, ocm_mode = (mode + "-Python").split('-')[0:2] benchmark.group = "Predator-Prey " + str(len(samples)) obs_len = 3 obs_coords = 2 @@ -188,7 +191,7 @@ def test_predator_prey(benchmark, mode, samples): ) agent_comp.add_controller(ocm) agent_comp.enable_controller = True - ocm.comp_execution_mode = mode + ocm.comp_execution_mode = ocm_mode input_dict = {player_obs:[[1.1576537, 0.60782117]], predator_obs:[[-0.03479106, -0.47666293]], From 8d9086f2b6acc376c9b3f3c69cc1c8e7ffc6accb Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Wed, 24 Jun 2020 11:34:03 -0400 Subject: [PATCH 17/27] cuda: Allow configurable thread block size Default to 32 Exist kernels early if id is larger than requested thread count. Signed-off-by: Jan Vesely --- psyneulink/core/llvm/__init__.py | 10 ++++++---- psyneulink/core/llvm/builder_context.py | 14 +++++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/psyneulink/core/llvm/__init__.py b/psyneulink/core/llvm/__init__.py index 23db92a5260..7bb4aeb4dc5 100644 --- a/psyneulink/core/llvm/__init__.py +++ b/psyneulink/core/llvm/__init__.py @@ -88,12 +88,14 @@ def _cuda_kernel(self): self.__cuda_kernel = _ptx_engine.get_kernel(self.name) return self.__cuda_kernel - def cuda_call(self, *args, threads=1): - self._cuda_kernel(*args, block=(1, 1, 1), grid=(threads, 1)) + def cuda_call(self, *args, threads=1, block_size=32): + self._cuda_kernel(*args, np.int32(threads), + block=(block_size, 1, 1), + grid=((threads + block_size) // block_size, 1)) - def cuda_wrap_call(self, *args, threads=1): + def cuda_wrap_call(self, *args, threads=1, block_size=32): wrap_args = (jit_engine.pycuda.driver.InOut(a) if isinstance(a, np.ndarray) else a for a in args) - self.cuda_call(*wrap_args, threads=threads) + self.cuda_call(*wrap_args, threads=threads, block_size=block_size) @staticmethod @functools.lru_cache(maxsize=32) diff --git a/psyneulink/core/llvm/builder_context.py b/psyneulink/core/llvm/builder_context.py index 75b635f6cab..126cef3a27a 100644 --- a/psyneulink/core/llvm/builder_context.py +++ b/psyneulink/core/llvm/builder_context.py @@ -324,7 +324,10 @@ def _gen_cuda_kernel_wrapper_module(function): decl_f = ir.Function(module, function.type.pointee, function.name) assert decl_f.is_declaration - kernel_func = ir.Function(module, function.type.pointee, function.name + "_cuda_kernel") + + wrapper_type = ir.FunctionType(ir.VoidType(), (*function.type.pointee.args, + ir.IntType(32))) + kernel_func = ir.Function(module, wrapper_type, function.name + "_cuda_kernel") block = kernel_func.append_basic_block(name="entry") builder = ir.IRBuilder(block) @@ -336,8 +339,13 @@ def _gen_cuda_kernel_wrapper_module(function): global_id = builder.mul(builder.call(ctaid_x_f, []), builder.call(ntid_x_f, [])) global_id = builder.add(global_id, builder.call(tid_x_f, [])) - # Index all pointer arguments - args = list(kernel_func.args) + # Check global id and exit if we're over + should_quit = builder.icmp_unsigned(">=", global_id, kernel_func.args[-1]) + with builder.if_then(should_quit): + builder.ret_void() + + # Index all pointer arguments. Ignore the thread count argument + args = list(kernel_func.args)[:-1] indexed_args = [] is_grid_evaluate = len(args) == 8 From 7e8cb03c098a50312c0e8c734cc7be5881955962 Mon Sep 17 00:00:00 2001 From: jdcpni Date: Wed, 24 Jun 2020 20:06:27 -0400 Subject: [PATCH 18/27] Refactor/showgraph/node role controller (#1691) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * • showgraph.py - allow inport_port on input_CIM for Target node of nested comp to have no afferents - make Target node orange, and BOLD if INPUT node • Project: require_projection_in_composition -> _require_projection_in_composition * • showgraph.py - allow inport_port on input_CIM for Target node of nested comp to have no afferents * • showgraph.py - allow inport_port on input_CIM for Target node of nested comp to have no afferents - Target node color -> organge, and use bold_width * • composition.py show_graph: added args (for IDE detection) * • composition.py show_graph: added args (for IDE detection) NodeRole: added CONTROLLER but current commented out, pending discussion * • composition.py NodeRole: added CONTROLLER but current commented out, pending discussion * • composition.py show_graph: added args (for IDE detection) * • showgraph.py enclosing_g as arg to helper methods replaced by enclosing_comp (and then constructed locally) * • showgraph.py _is_composition_controller and _trace_senders_for_controller modified to use NodeRole.CONTROLLER * - * • composition.py - _determine_node_roles: added assignment of NodeRole.CONTROLLER to controller * - * - * • showgraph.py - show_graph(): - BUG for show_node_structure + show_cim + show_nested=NESTED: if the first node of a nested composition receives *a single* ControlProjection from a ControlMechanism that is not a controller in the enclosing composition, the ControlProjection is not properly shown as projecting from the ControlSignal OutputPort of the ControlMechanism to the corresponding InputPort of the parameter_CIM of the nested Composition; works fine if ControlProjection is from a controller; if it is to a node that is not the first node of the nested Composition; or if there is more than one ControlProjection (to either the same node or a different one within the nested composition). Seems to be some "memory leak"/carryover from processing input_cim in _assign_cim_components. * • showgraph.py - show_graph(): refactor _assign_cim_components to use _render_projection • composition.py - added cims attribute with list of Composition's 3 cims * - * • test_show_graph.py - last test in test_of_show_nested_show_cim_and_show_node_structure commented out unitl add_nodes/add_linear_processing_pathway bug is fixed * - * - * - * - Co-authored-by: jdcpni --- psyneulink/core/compositions/composition.py | 21 +- psyneulink/core/compositions/showgraph.py | 254 ++++++++------------ tests/composition/test_show_graph.py | 99 ++++++-- 3 files changed, 197 insertions(+), 177 deletions(-) diff --git a/psyneulink/core/compositions/composition.py b/psyneulink/core/compositions/composition.py index 7f7f7624c60..fe93461854c 100644 --- a/psyneulink/core/compositions/composition.py +++ b/psyneulink/core/compositions/composition.py @@ -413,9 +413,12 @@ A `controller ` can be assigned either by specifying it in the **controller** argument of the Composition's constructor, or using its `add_controller ` method. +COMMENT: +The Node is assigned the `NodeRole` `CONTROLLER`. +COMMENT COMMENT: -TBI FOR COMPOSITION +TBI FOR COMPOSITION˚ CONTROLLER CAN BE SPECIFIED BY AS True, BY CLASS (E.G., OCM), OR CONSTRUCTOR IF TRUE, CLASS OR BY CONSTRUCTOR WITHOUT OBJECTIVE_MECHANISM SPEC, A DEFAULT IS OBJ_MECH IS CREATED IF A DEFAULT OBJ MECH IS CREATED, OR NEITHER OBJ_MECH NOR OCM HAVE MONITOR FOR CONTROL SPECIFIED, THEN @@ -3125,6 +3128,10 @@ class Composition(Composition_Base, metaclass=ComponentsMeta): efferents : ContentAddressableList[`Projection `] a list of all of the `Projections ` from the Composition's `output_CIM`. + cims : list + a list containing references to the Composition's `input_CIM `, + `parameter_CIM `, and `output_CIM `. + env : Gym Forager Environment : default: None stores a Gym Forager Environment so that the Composition may interact with this environment within a single call to `run `. @@ -3316,6 +3323,7 @@ def __init__( self.output_CIM = CompositionInterfaceMechanism(name=self.name + " Output_CIM", composition=self, port_map=self.output_CIM_ports) + self.cims = [self.input_CIM, self.parameter_CIM, self.output_CIM] self.shadows = {} @@ -3895,10 +3903,11 @@ def get_roles_by_node(self, node): List[`Mechanisms ` and/or `Compositions `] : list of `NodeRoles ` assigned to **node**. """ + try: return self.nodes_to_roles[node] except KeyError: - raise CompositionError('Node {0} not found in {1}.nodes_to_roles'.format(node, self)) + raise CompositionError(f"Node {node} not found in {self.nodes_to_roles}.") def get_nodes_by_role(self, role): """ @@ -4298,7 +4307,10 @@ def _clear_node_roles(self, node): def _add_node_role(self, node, role): if role not in NodeRole: raise CompositionError('Invalid NodeRole: {0}'.format(role)) - self.nodes_to_roles[node].add(role) + try: + self.nodes_to_roles[node].add(role) + except KeyError: + raise CompositionError(f"Attempt to assign {role} to '{node.name}' that is not a Node in {self.name}.") def _remove_node_role(self, node, role): if role not in NodeRole: @@ -6960,6 +6972,9 @@ def add_controller(self, controller:ControlMechanism): controller.composition = self self.controller = controller + # Having controller in nodes is not currently supported (due to special handling of scheduling/execution); + # its NodeRole assignment is handled directly by the get_nodes_by_role and get_roles_by_node methods. + # self._add_node_role(controller, NodeRole.CONTROLLER) # ADD AUX_COMPONENTS RELEVANT TO CONTROLLER diff --git a/psyneulink/core/compositions/showgraph.py b/psyneulink/core/compositions/showgraph.py index d52b137aab1..5e3bb0d0b32 100644 --- a/psyneulink/core/compositions/showgraph.py +++ b/psyneulink/core/compositions/showgraph.py @@ -252,7 +252,7 @@ EXECUTION_SET = 'EXECUTION_SET' # Values for nested Compositions (passed from level to level) -ENCLOSING_G = 'enclosing_g' +ENCLOSING_COMP = 'enclosing_comp' # enclosing composition NESTING_LEVEL = 'nesting_level' NUM_NESTING_LEVELS = 'num_nesting_levels' @@ -618,10 +618,11 @@ def show_graph(self, context.execution_id = composition.default_execution_id # Args not specified by user but used in calls to show_graph for nested Compositions - enclosing_g = kwargs.pop(ENCLOSING_G,None) + enclosing_comp = kwargs.pop(ENCLOSING_COMP,None) nesting_level = kwargs.pop(NESTING_LEVEL,None) self.num_nesting_levels = kwargs.pop(NUM_NESTING_LEVELS,None) + enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None processing_graph = composition.graph_processing.dependency_dict # Validate active_items ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -674,7 +675,7 @@ def show_graph(self, # For outermost Composition: # - initialize nesting level # - set num_nesting_levels - if enclosing_g is None: + if enclosing_comp is None: # initialize nesing_level nesting_level = 0 # show_nested specified number of nested levels to show, so set to that @@ -756,9 +757,8 @@ def show_graph(self, self._assign_processing_components(G, rcvr, - composition, processing_graph, - enclosing_g, + enclosing_comp, nesting_level, active_items, show_nested, @@ -774,8 +774,7 @@ def show_graph(self, # Add cim Components to graph if show_cim if show_cim: self._assign_cim_components(G, - [composition.input_CIM, composition.parameter_CIM, composition.output_CIM], - enclosing_g, + enclosing_comp, active_items, show_nested, show_types, @@ -802,7 +801,7 @@ def show_graph(self, if show_learning: self._assign_learning_components(G, processing_graph, - enclosing_g, + enclosing_comp, active_items, show_nested, show_cim, @@ -814,6 +813,7 @@ def show_graph(self, show_projection_labels) return self._generate_output(G, + enclosing_comp, active_items, show_controller, output_fmt, @@ -825,9 +825,8 @@ def __call__(self, **args): def _assign_processing_components(self, g, rcvr, - composition, processing_graph, - enclosing_g, + enclosing_comp, nesting_level, active_items, show_nested, @@ -844,13 +843,14 @@ def _assign_processing_components(self, from psyneulink.core.compositions.composition import Composition, NodeRole composition = self.composition + enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None # User passed attrs for nested Composition if isinstance(rcvr, Composition): if show_nested: nested_args.update({OUTPUT_FMT:'gv', # 'composition': rcvr, - ENCLOSING_G:g, + ENCLOSING_COMP:composition, NESTING_LEVEL:nesting_level + 1}) # Get subgraph for nested Composition nested_comp_graph = rcvr._show_graph.show_graph(**nested_args) @@ -1034,12 +1034,11 @@ def _assign_processing_components(self, show_dimensions, show_node_structure, show_projection_labels, - enclosing_g=enclosing_g) + enclosing_comp=enclosing_comp) def _assign_cim_components(self, g, - cims, - enclosing_g, + enclosing_comp, active_items, show_nested, show_types, @@ -1050,10 +1049,32 @@ def _assign_cim_components(self, from psyneulink.core.compositions.composition import Composition, NodeRole composition = self.composition + enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None cim_rank = 'same' - for cim in cims: + def _render_projection(_g, proj, sndr_label, rcvr_label, + proj_color=self.default_node_color, + arrowhead=self.default_projection_arrow): + if any(item in active_items for item in {proj, proj.sender.owner}): + if self.active_color == BOLD: + color = proj_color + else: + color = self.active_color + proj_width = str(self.default_width + self.active_thicker_by) + composition.active_item_rendered = True + else: + color = proj_color + proj_width = str(self.default_width) + + if show_projection_labels: + label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) + else: + label = '' + + _g.edge(sndr_label, rcvr_label, label=label, color=color, penwidth=proj_width, arrowhead=arrowhead) + + for cim in composition.cims: # Skip cim if it is not doing anything if not (cim.afferents or cim.efferents): @@ -1072,7 +1093,7 @@ def _assign_cim_components(self, # But if any Projection to it is from a controller, use controller_color for input_port in cim.input_ports: for proj in input_port.path_afferents: - if self._trace_senders_for_controller(proj): + if self._trace_senders_for_controller(proj, enclosing_comp): cim_type_color = self.controller_color elif cim is composition.output_CIM: cim_type_color = self.output_color @@ -1114,7 +1135,7 @@ def _assign_cim_components(self, rank=cim_rank, penwidth=cim_penwidth) - # FIX 6/2/20: THIS CAN BE CONDENSED (ABSTACTED INTO GENERIC FUNCTION TAKING cim-SPECIFIC PARAMETERS) + # FIX 6/2/20: THIS CAN BE CONDENSED (ABSTRACTED INTO GENERIC FUNCTION TAKING cim-SPECIFIC PARAMETERS) # ASSIGN CIM PROJECTIONS **************************************************************** # INPUT_CIM ----------------------------------------------------------------------------- @@ -1160,23 +1181,7 @@ def _assign_cim_components(self, sndr_output_node_proj_label = sndr_label # Render Projection - if any(item in active_items for item in {proj, proj.sender.owner}): - if self.active_color == BOLD: - proj_color = self.default_node_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = self.default_node_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - - enclosing_g.edge(sndr_output_node_proj_label, rcvr_cim_proj_label, label=label, - color=proj_color, penwidth=proj_width) + _render_projection(enclosing_g, proj, sndr_output_node_proj_label, rcvr_cim_proj_label) # Projections from input_CIM to INPUT nodes for output_port in composition.input_CIM.output_ports: @@ -1210,7 +1215,7 @@ def _assign_cim_components(self, # Construct edge name if show_node_structure: # Get label for CIM's port as edge's sender - sndr_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" + sndr_input_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" if (isinstance(rcvr_input_node_proj_owner, Composition) and show_nested is not NESTED): rcvr_input_node_proj_label = rcvr_label @@ -1223,30 +1228,15 @@ def _assign_cim_components(self, # f"{rcvr_label}:" \ # f"{rcvr_input_node_proj_owner._get_port_name(rcvr_input_node_proj)}" else: - sndr_cim_proj_label = cim_label + sndr_input_cim_proj_label = cim_label rcvr_input_node_proj_label = rcvr_label # Render Projection - if any(item in active_items for item in {proj, proj.receiver.owner}): - if self.active_color == BOLD: - proj_color = self.default_node_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = self.default_node_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - g.edge(sndr_cim_proj_label, rcvr_input_node_proj_label, label=label, - color=proj_color, penwidth=proj_width) + _render_projection(g, proj, sndr_input_cim_proj_label, rcvr_input_node_proj_label) # PARAMETER_CIM ------------------------------------------------------------------------- - if cim is composition.parameter_CIM: + elif cim is composition.parameter_CIM: # Projections from ControlMechanism(s) in enclosing Composition to parameter_CIM # (other than from controller; that is handled in _assign_controller_compoents) @@ -1267,12 +1257,10 @@ def _assign_cim_components(self, f"PROGRAM ERROR: parameter_CIM of {composition.name} recieves a Projection " \ f"from a Node from other than a {ControlMechanism.__name__}." # Skip Projections from controller (handled in _assign_controller_components) - # if self._is_composition_controller(owner): # FIX: 6/11/20 - REPLACE AFTER TESTS - if (hasattr(ctl_mech_output_port_owner, 'composition') - and ctl_mech_output_port_owner.composition): + if self._is_composition_controller(ctl_mech_output_port_owner, enclosing_comp): continue # Skip if there is no outer Composition (enclosing_g), - # or Projections acorss nested Compositions are not being shown (show_nested=INSET) + # or Projections across nested Compositions are not being shown (show_nested=INSET) if not enclosing_g or show_nested is INSET: continue sndr_label = self._get_graph_node_label(composition, @@ -1281,31 +1269,17 @@ def _assign_cim_components(self, # Construct edge name if show_node_structure: # Get label for ctl_mech's OutputPrt as edge's sender - sndr_output_node_proj_label = \ + sndr_ctl_sig_proj_label = \ f"{sndr_label}:{OutputPort.__name__}-{proj.sender.name}" # Get label for CIM's InputPort as edge's receiver - rcvr_cim_proj_label = f"{cim_label}:{InputPort.__name__}-{proj.receiver.name}" + rcvr_param_cim_proj_label = f"{cim_label}:{InputPort.__name__}-{proj.receiver.name}" else: - sndr_output_node_proj_label = sndr_label - rcvr_cim_proj_label = cim_label + sndr_ctl_sig_proj_label = sndr_label + rcvr_param_cim_proj_label = cim_label # Render Projection - if any(item in active_items for item in {proj, proj.sender.owner}): - if self.active_color == BOLD: - proj_color = self.control_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = self.control_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - enclosing_g.edge(sndr_output_node_proj_label, rcvr_cim_proj_label, label=label, - color=proj_color, penwidth=proj_width) + _render_projection(enclosing_g, proj, sndr_ctl_sig_proj_label, rcvr_param_cim_proj_label, + self.control_color) # Projections from parameter_CIM to Nodes that are being modulated for output_port in composition.parameter_CIM.output_ports: @@ -1330,47 +1304,35 @@ def _assign_cim_components(self, # Construct edge name if show_node_structure: # Get label for CIM's port as edge's sender - sndr_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" + sndr_param_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" if (isinstance(rcvr_modulated_mech_proj_owner, Composition) and not show_nested is not NESTED): rcvr_modulated_mec_proj_label = rcvr_label else: - # Need to use direct reference to proj.receiver rather than rcvr_modulated_mec_proj + # Need to use direct reference to proj.receiver rather than rcvr_modulated_mech_proj # since could be Composition, which does not have a get_port_name attribute rcvr_modulated_mec_proj_label = \ f"{rcvr_label}:{ParameterPort.__name__}-{proj.receiver.name}" # rcvr_modulated_mec_proj_label = \ # f"{rcvr_label}:" \ - # f"{rcvr_input_node_proj_owner._get_port_name(rcvr_modulated_mec_proj)}" + # f"{rcvr_input_node_proj_owner._get_port_name(rcvr_modulated_mech_proj)}" else: - sndr_cim_proj_label = cim_label + sndr_param_cim_proj_label = cim_label rcvr_modulated_mec_proj_label = rcvr_label # Render Projection - if self._trace_senders_for_controller(proj): + if self._trace_senders_for_controller(proj, enclosing_comp): ctl_proj_color = self.controller_color else: ctl_proj_color = self.control_color - if any(item in active_items for item in {proj, proj.receiver.owner}): - if self.active_color == BOLD: - proj_color = ctl_proj_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = ctl_proj_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - g.edge(sndr_cim_proj_label, rcvr_modulated_mec_proj_label, label=label, - color=proj_color, arrowhead=self.control_projection_arrow, penwidth=proj_width) + + _render_projection(g, proj, sndr_param_cim_proj_label, rcvr_modulated_mec_proj_label, + proj_color=ctl_proj_color, arrowhead=self.control_projection_arrow) + # OUTPUT_CIM ---------------------------------------------------------------------------- - if cim is composition.output_CIM: + elif cim is composition.output_CIM: # Projections from OUTPUT nodes to output_CIM for input_port in composition.output_CIM.input_ports: @@ -1383,7 +1345,6 @@ def _assign_cim_components(self, sndr_output_node_proj_owner = sndr_output_node_proj.owner.composition else: sndr_output_node_proj_owner = sndr_output_node_proj.owner - # Validate the Projection is from an OUTPUT node if ((sndr_output_node_proj_owner in composition.nodes_to_roles and not NodeRole.OUTPUT in composition.nodes_to_roles[sndr_output_node_proj_owner])): @@ -1394,10 +1355,11 @@ def _assign_cim_components(self, sndr_label = self._get_graph_node_label(composition, sndr_output_node_proj_owner, show_types, show_dimensions) + # Construct edge name if show_node_structure: # Get label of CIM's port as edge's receiver - rcvr_cim_proj_label = f"{cim_label}:{InputPort.__name__}-{proj.receiver.name}" + rcvr_output_cim_proj_label = f"{cim_label}:{InputPort.__name__}-{proj.receiver.name}" if (isinstance(sndr_output_node_proj_owner, Composition) and show_nested is not NESTED): sndr_output_node_proj_label = sndr_label @@ -1411,25 +1373,11 @@ def _assign_cim_components(self, # f"{sndr_output_node_proj_owner._get_port_name(sndr_output_node_proj)}" else: sndr_output_node_proj_label = sndr_label - rcvr_cim_proj_label = cim_label + rcvr_output_cim_proj_label = cim_label + # FIX 6/23/20 PROBLEM POINT: # Render Projection - if any(item in active_items for item in {proj, proj.receiver.owner}): - if self.active_color == BOLD: - proj_color = self.default_node_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = self.default_node_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - g.edge(sndr_output_node_proj_label, rcvr_cim_proj_label, label=label, - color=proj_color, penwidth=proj_width) + _render_projection(g, proj, sndr_output_node_proj_label, rcvr_output_cim_proj_label) # Projections from output_CIM to Node(s) in enclosing Composition for output_port in composition.output_CIM.output_ports: @@ -1449,10 +1397,11 @@ def _assign_cim_components(self, rcvr_label = self._get_graph_node_label(composition, rcvr_node_input_port_owner, show_types, show_dimensions) + # Construct edge name if show_node_structure: # Get label of CIM's port as edge's receiver - sndr_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" + sndr_output_cim_proj_label = f"{cim_label}:{OutputPort.__name__}-{proj.sender.name}" if (isinstance(rcvr_node_input_port_owner, Composition) and show_nested is not NESTED): rcvr_input_node_proj_label = rcvr_label @@ -1466,25 +1415,11 @@ def _assign_cim_components(self, # f"{sndr_output_node_proj_owner._get_port_name(sndr_output_node_proj)}" else: rcvr_input_node_proj_label = rcvr_label - sndr_cim_proj_label = cim_label + sndr_output_cim_proj_label = cim_label # Render Projection - if any(item in active_items for item in {proj, proj.sender.owner}): - if self.active_color == BOLD: - proj_color = self.default_node_color - else: - proj_color = self.active_color - proj_width = str(self.default_width + self.active_thicker_by) - composition.active_item_rendered = True - else: - proj_color = self.default_node_color - proj_width = str(self.default_width) - if show_projection_labels: - label = self._get_graph_node_label(composition, proj, show_types, show_dimensions) - else: - label = '' - enclosing_g.edge(sndr_cim_proj_label, rcvr_input_node_proj_label, label=label, - color=proj_color, penwidth=proj_width) + _render_projection(enclosing_g, proj, sndr_output_cim_proj_label, rcvr_input_node_proj_label) + def _assign_controller_components(self, g, @@ -1797,13 +1732,12 @@ def find_rcvr_comp(r, c, l): show_dimensions, show_node_structure, show_projection_labels, - proj_color=ctl_proj_color, - enclosing_g=None) + proj_color=ctl_proj_color) def _assign_learning_components(self, g, processing_graph, - enclosing_g, + enclosing_comp, active_items, show_nested, show_cim, @@ -1817,6 +1751,7 @@ def _assign_learning_components(self, from psyneulink.core.compositions.composition import NodeRole composition = self.composition + enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None # Get learning_components, with exception of INPUT (i.e. TARGET) nodes # (i.e., allow TARGET node to continue to be marked as an INPUT node) @@ -1886,7 +1821,7 @@ def _assign_learning_components(self, show_dimensions, show_node_structure, show_projection_labels, - enclosing_g=enclosing_g) + enclosing_comp=enclosing_comp) def _render_projection_as_node(self, g, @@ -1973,10 +1908,11 @@ def _assign_incoming_edges(self, show_projection_labels, proj_color=None, proj_arrow=None, - enclosing_g=None): + enclosing_comp=None): from psyneulink.core.compositions.composition import Composition, NodeRole composition = self.composition + enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None proj_color_default = proj_color or self.default_node_color proj_arrow_default = proj_arrow or self.default_projection_arrow @@ -2042,12 +1978,13 @@ def _assign_incoming_edges(self, continue assert num_afferents==1, f"PROGRAM ERROR: {sender} of {composition.name} " \ f"doesn't have exactly one afferent Projection." + # Get node from enclosing Comopsition that is source of sender sndr = sender.port_map[proj.receiver][0].path_afferents[0].sender.owner # Skip: - # - cims as sources (handled in _assign_cim_compmoents) + # - cims as sources (handled in _assign_cim_componoents) # - controller (handled in _assign_controller_components) if (isinstance(sndr, CompositionInterfaceMechanism) - or self._is_composition_controller(sndr)): + or self._is_composition_controller(sndr ,enclosing_comp)): continue if sender is composition.parameter_CIM: proj_color = self.control_color @@ -2131,7 +2068,11 @@ def _assign_incoming_edges(self, or sndr in composition.learning_components) if isinstance(sender, ControlMechanism): proj_color = self.control_color - proj_arrowhead = self.control_projection_arrow + if (not isinstance(rcvr, Composition) + or (not show_cim and + (show_nested is not NESTED) + or (show_nested is False))): + proj_arrowhead = self.control_projection_arrow # Check if Projection or its receiver is active if any(item in active_items for item in {proj, proj.receiver.owner}): if self.active_color == BOLD: @@ -2197,6 +2138,7 @@ def _assign_incoming_edges(self, def _generate_output(self, G, + enclosing_comp, active_items, show_controller, output_fmt, @@ -2247,7 +2189,9 @@ def get_index_of_node_in_G_body(node, node_type:tc.enum(MECHANISM, PROJECTION, C for proj in composition.projections: # Put ControlProjection(s) last, except for controller of Composition (see below) - if isinstance(proj, ControlProjection) and self._is_composition_controller(proj.sender.owner): + # if isinstance(proj, ControlProjection) and self._is_composition_controller(proj.sender.owner): + if isinstance(proj, ControlProjection) and self._is_composition_controller(proj.sender.owner, + enclosing_comp): i = get_index_of_node_in_G_body(proj, PROJECTION) if i is not None: G.body.insert(len(G.body),G.body.pop(i)) @@ -2303,18 +2247,28 @@ def get_index_of_node_in_G_body(node, node_type:tc.enum(MECHANISM, PROJECTION, C except: raise ShowGraphError(f"Problem displaying graph for {composition.name}") - def _is_composition_controller(self, mech): + def _is_composition_controller(self, mech, enclosing_comp=None): # FIX 6/12/20: REPLACE WITH TEST FOR NodeRole.CONTROLLER ONCE THAT IS IMPLEMENTED - return isinstance(mech, ControlMechanism) and hasattr(mech, 'composition') and mech.composition + # return isinstance(mech, ControlMechanism) and hasattr(mech, 'composition') and mech.composition + from psyneulink.core.compositions.composition import NodeRole + if not isinstance(mech, ControlMechanism): + return False + for comp in [self.composition, enclosing_comp]: + if not comp: + continue + if mech in comp._all_nodes and NodeRole.CONTROLLER in comp.get_roles_by_node(mech): + return True + return False - def _trace_senders_for_controller(self, proj): + def _trace_senders_for_controller(self, proj, comp=None): """Check whether source sender of a ControlProjection is (at any level of nesting) a Composition controller.""" owner = proj.sender.owner - if self._is_composition_controller(owner): + comp = comp or self.composition + if self._is_composition_controller(owner, comp): return True if isinstance(owner, CompositionInterfaceMechanism): sender_proj = next(v[0] for k,v in owner.port_map.items() if v[1] is proj.sender).path_afferents[0] - return self._trace_senders_for_controller(sender_proj) + return self._trace_senders_for_controller(sender_proj, comp) return False def _get_graph_node_label(self, composition, item, show_types=None, show_dimensions=None): diff --git a/tests/composition/test_show_graph.py b/tests/composition/test_show_graph.py index bc509bcf6a3..115f304a0ef 100644 --- a/tests/composition/test_show_graph.py +++ b/tests/composition/test_show_graph.py @@ -226,7 +226,7 @@ def test_multiple_nesting_levels_with_control_mech_projection_one_level_deep(sel gv = ocomp.show_graph(show_nested=INSET, output_fmt='source') assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\tmcomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> mcomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> mcomp [label="" arrowhead=normal color=black penwidth=1]\n\tmcomp -> ob [label="" arrowhead=normal color=black penwidth=1]\n\tob -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tob [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tsubgraph cluster_mcomp {\n\t\tgraph [label=mcomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tma [color=green penwidth=3 rank=source shape=oval]\n\t\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\t\tma -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\t\ticomp -> mb [label="" arrowhead=normal color=black penwidth=1]\n\t\tmb [color=red penwidth=3 rank=max shape=oval]\n\t\tsubgraph cluster_icomp {\n\t\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\t\tedge [fontname=arial fontsize=10]\n\t\t\tia [color=green penwidth=3 rank=source shape=oval]\n\t\t\tia -> ib [label="" arrowhead=normal color=black penwidth=1]\n\t\t\tib [color=red penwidth=3 rank=max shape=oval]\n\t\t\tlabel=icomp\n\t\t}\n\t\tlabel=mcomp\n\t}\n}' gv = ocomp.show_graph(show_nested=2, show_cim=True, show_node_structure=True, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> "mcomp INPUT":"InputPort-INPUT_CIM_ma_InputPort-0" [label="" color=black penwidth=1]\n\tctl_mech:"OutputPort-ma[slope] ControlSignal" -> "mcomp CONTROL":"InputPort-PARAMETER_CIM_ma_slope" [label="" color=blue penwidth=1]\n\t"mcomp OUTPUT":"OutputPort-OUTPUT_CIM_mb_RESULT" -> ob:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" color=black penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ma[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tsubgraph cluster_mcomp {\n\t\tgraph [label=mcomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tma [label=<
RESULT
OutputPorts
Mechanism:
ma
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\tma:"OutputPort-RESULT" -> "icomp INPUT":"InputPort-INPUT_CIM_ia_InputPort-0" [label="" color=black penwidth=1]\n\t\t"icomp OUTPUT":"OutputPort-OUTPUT_CIM_ib_RESULT" -> mb:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"mcomp INPUT" [label=<
INPUT_CIM_ma_InputPort-0
OutputPorts
Mechanism:
mcomp Input_CIM
InputPorts
INPUT_CIM_ma_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"mcomp INPUT":"OutputPort-INPUT_CIM_ma_InputPort-0" -> ma:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"mcomp CONTROL" [label=<
PARAMETER_CIM_ma_slope
OutputPorts
Mechanism:
mcomp Parameter_CIM
InputPorts
PARAMETER_CIM_ma_slope
> color=blue penwidth=1 rank=same shape=plaintext]\n\t\t"mcomp CONTROL":"OutputPort-PARAMETER_CIM_ma_slope" -> ma:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"mcomp OUTPUT" [label=<
OUTPUT_CIM_mb_RESULT
OutputPorts
Mechanism:
mcomp Output_CIM
InputPorts
OUTPUT_CIM_mb_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tmb:"OutputPort-RESULT" -> "mcomp OUTPUT":"InputPort-OUTPUT_CIM_mb_RESULT" [label="" color=black penwidth=1]\n\t\tmb [label=<
RESULT
OutputPorts
Mechanism:
mb
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tsubgraph cluster_icomp {\n\t\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\t\tedge [fontname=arial fontsize=10]\n\t\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t\tia:"OutputPort-RESULT" -> ib:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
InputPorts
INPUT_CIM_ia_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t\t"icomp OUTPUT" [label=<
OUTPUT_CIM_ib_RESULT
OutputPorts
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ib_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t\tib:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ib_RESULT" [label="" color=black penwidth=1]\n\t\t\tib [label=<
RESULT
OutputPorts
Mechanism:
ib
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\t\tlabel=icomp\n\t\t}\n\t\tlabel=mcomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> "mcomp INPUT":"InputPort-INPUT_CIM_ma_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech:"OutputPort-ma[slope] ControlSignal" -> "mcomp CONTROL":"InputPort-PARAMETER_CIM_ma_slope" [label="" arrowhead=normal color=blue penwidth=1]\n\t"mcomp OUTPUT":"OutputPort-OUTPUT_CIM_mb_RESULT" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ma[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tsubgraph cluster_mcomp {\n\t\tgraph [label=mcomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tma [label=<
RESULT
OutputPorts
Mechanism:
ma
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\tma:"OutputPort-RESULT" -> "icomp INPUT":"InputPort-INPUT_CIM_ia_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp OUTPUT":"OutputPort-OUTPUT_CIM_ib_RESULT" -> mb:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"mcomp INPUT" [label=<
INPUT_CIM_ma_InputPort-0
OutputPorts
Mechanism:
mcomp Input_CIM
InputPorts
INPUT_CIM_ma_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"mcomp INPUT":"OutputPort-INPUT_CIM_ma_InputPort-0" -> ma:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"mcomp CONTROL" [label=<
PARAMETER_CIM_ma_slope
OutputPorts
Mechanism:
mcomp Parameter_CIM
InputPorts
PARAMETER_CIM_ma_slope
> color=blue penwidth=1 rank=same shape=plaintext]\n\t\t"mcomp CONTROL":"OutputPort-PARAMETER_CIM_ma_slope" -> ma:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"mcomp OUTPUT" [label=<
OUTPUT_CIM_mb_RESULT
OutputPorts
Mechanism:
mcomp Output_CIM
InputPorts
OUTPUT_CIM_mb_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tmb:"OutputPort-RESULT" -> "mcomp OUTPUT":"InputPort-OUTPUT_CIM_mb_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tmb [label=<
RESULT
OutputPorts
Mechanism:
mb
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tsubgraph cluster_icomp {\n\t\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\t\tedge [fontname=arial fontsize=10]\n\t\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t\tia:"OutputPort-RESULT" -> ib:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
InputPorts
INPUT_CIM_ia_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t\t"icomp OUTPUT" [label=<
OUTPUT_CIM_ib_RESULT
OutputPorts
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ib_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t\tib:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ib_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\t\tib [label=<
RESULT
OutputPorts
Mechanism:
ib
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\t\tlabel=icomp\n\t\t}\n\t\tlabel=mcomp\n\t}\n}' def test_nested_learning(self): ia = ProcessingMechanism(name='INNER INPUT') @@ -245,10 +245,10 @@ def test_nested_learning(self): assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "INNER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"INNER OUTPUT" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n}' gv = ocomp.show_graph(show_nested=NESTED, show_cim=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "NESTED COMPOSITION INPUT" [label="" color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT" -> "OUTER OUTPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"NESTED COMPOSITION INPUT" -> "INNER INPUT" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" -> Target [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\t"INNER OUTPUT" -> "NESTED COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "NESTED COMPOSITION INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"NESTED COMPOSITION INPUT" -> "INNER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" -> Target [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\t"INNER OUTPUT" -> "NESTED COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=False, show_node_structure=True, show_learning=True, output_fmt='source') assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n}' @@ -257,10 +257,10 @@ def test_nested_learning(self): assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=True, show_node_structure=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n}' gv = ocomp.show_graph(show_nested=NESTED, show_cim=True, show_node_structure=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_INNER INPUT_InputPort-0" [label="" color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT":"OutputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [label=<
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Input_CIM
InputPorts
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_INNER INPUT_InputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_Target_InputPort-0" -> Target:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [label=<
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "NESTED COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_INNER INPUT_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT":"OutputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [label=<
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Input_CIM
InputPorts
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_INNER INPUT_InputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_Target_InputPort-0" -> Target:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [label=<
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "NESTED COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' def test_nested_learning_test_with_user_specified_target_in_outer_composition(self): ia = ProcessingMechanism(name='INNER INPUT') @@ -294,10 +294,10 @@ def test_nested_learning_test_with_user_specified_target_in_outer_composition(se assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [color=green penwidth=3 rank=source shape=oval]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "INNER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET -> Target [label="" arrowhead=normal color=orange penwidth=1]\n\t"INNER OUTPUT" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER -> INTERNAL [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [color=purple penwidth=1 rank=min shape=oval]\n\t"OBJECTIVE MECHANISM" -> CONTROLLER [label="" color=purple penwidth=1]\n\t"OUTER INPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tCONTROLLER [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [color=green penwidth=3 rank=source shape=oval]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" -> TARGET [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\tCONTROLLER -> INTERNAL [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [color=purple penwidth=1 rank=min shape=oval]\n\t"OBJECTIVE MECHANISM" -> CONTROLLER [label="" color=purple penwidth=1]\n\t"OUTER INPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tCONTROLLER [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [color=green penwidth=3 rank=source shape=oval]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" -> TARGET [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER -> INTERNAL [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [color=purple penwidth=1 rank=min shape=oval]\n\t"OBJECTIVE MECHANISM" -> CONTROLLER [label="" color=purple penwidth=1]\n\t"OUTER INPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tCONTROLLER [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' gv = ocomp.show_graph(show_nested=NESTED, show_cim=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [color=green penwidth=3 rank=source shape=oval]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "NESTED COMPOSITION INPUT" [label="" color=black penwidth=1]\n\tTARGET -> "NESTED COMPOSITION INPUT" [label="" color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT" -> "OUTER OUTPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" -> TARGET [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\tCONTROLLER -> INTERNAL [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [color=purple penwidth=1 rank=min shape=oval]\n\t"OBJECTIVE MECHANISM" -> CONTROLLER [label="" color=purple penwidth=1]\n\t"OUTER INPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tCONTROLLER [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"NESTED COMPOSITION INPUT" -> "INNER INPUT" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" -> Target [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\t"INNER OUTPUT" -> "NESTED COMPOSITION OUTPUT" [label="" color=black penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [color=green penwidth=3 rank=source shape=oval]\n\t"OUTER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\tINTERNAL [color=black penwidth=1 rank=same shape=oval]\n\t"OUTER INPUT" -> INTERNAL [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL -> "NESTED COMPOSITION INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET -> "NESTED COMPOSITION INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT" -> "OUTER OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"COMPOSITION INPUT" -> "OUTER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" -> TARGET [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t"OUTER OUTPUT" -> "COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER -> INTERNAL [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [color=purple penwidth=1 rank=min shape=oval]\n\t"OBJECTIVE MECHANISM" -> CONTROLLER [label="" color=purple penwidth=1]\n\t"OUTER INPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" -> "OBJECTIVE MECHANISM" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\tCONTROLLER [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [color=orange penwidth=3 rank=min shape=oval]\n\t\t"INNER INPUT" [color=green penwidth=3 rank=source shape=oval]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"NESTED COMPOSITION INPUT" -> "INNER INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" -> Target [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\t"INNER OUTPUT" -> "NESTED COMPOSITION OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tComparator [color=orange penwidth=1 rank=min shape=oval]\n\t\t"INNER OUTPUT" -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget -> Comparator [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=orange penwidth=1 rank=min shape=oval]\n\t\tComparator -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [color=red penwidth=3 rank=max shape=oval]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=False, show_node_structure=True, show_learning=True, output_fmt='source') assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' @@ -306,10 +306,10 @@ def test_nested_learning_test_with_user_specified_target_in_outer_composition(se assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> Target:"InputPort-InputPort-0" [label="" arrowhead=normal color=orange penwidth=1]\n\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' gv = ocomp.show_graph(show_nested=False, show_cim=True, show_node_structure=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0INPUT_CIM_TARGET_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_TARGET_InputPort-0" -> TARGET:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" [color=pink penwidth=3 rank=same shape=rectangle]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0INPUT_CIM_TARGET_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_TARGET_InputPort-0" -> TARGET:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' gv = ocomp.show_graph(show_nested=NESTED, show_cim=True, show_node_structure=True, show_learning=True, output_fmt='source') - assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_INNER INPUT_InputPort-0" [label="" color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_Target_InputPort-0" [label="" color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT":"OutputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0INPUT_CIM_TARGET_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_TARGET_InputPort-0" -> TARGET:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [label=<
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Input_CIM
InputPorts
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_INNER INPUT_InputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_Target_InputPort-0" -> Target:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [label=<
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "NESTED COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" [label="" color=black penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' + assert gv == 'digraph COMPOSITION {\n\tgraph [label=COMPOSITION overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\tTARGET [label=<
OutputPort-0
OutputPorts
Mechanism:
TARGET
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t"OUTER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\tINTERNAL [label=<
OutputPort-0
OutputPorts
Mechanism:
INTERNAL
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=black penwidth=1 rank=same shape=plaintext]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> INTERNAL:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tINTERNAL:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_INNER INPUT_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tTARGET:"OutputPort-OutputPort-0" -> "NESTED COMPOSITION INPUT":"InputPort-INPUT_CIM_Target_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"NESTED COMPOSITION OUTPUT":"OutputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" -> "OUTER OUTPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT" [label=<
INPUT_CIM_OUTER INPUT_InputPort-0INPUT_CIM_TARGET_InputPort-0
OutputPorts
Mechanism:
COMPOSITION Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_OUTER INPUT_InputPort-0" -> "OUTER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION INPUT":"OutputPort-INPUT_CIM_TARGET_InputPort-0" -> TARGET:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"COMPOSITION OUTPUT" [label=<
Mechanism:
COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_OUTER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_OUTER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tCONTROLLER:"OutputPort-INTERNAL[slope] ControlSignal" -> INTERNAL:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t"OBJECTIVE MECHANISM" [label=<
OUTCOME
OutputPorts
Mechanism:
OBJECTIVE MECHANISM
ParameterPorts
offset
scale
InputPorts
Value of OUTER INPUT [OutputPort-0]Value of OUTER OUTPUT [OutputPort-0]
> color=purple penwidth=1 rank=min shape=plaintext]\n\t"OBJECTIVE MECHANISM":"OutputPort-OUTCOME" -> CONTROLLER:"InputPort-OUTCOME" [label="" color=purple penwidth=1]\n\t"OUTER INPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER INPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT":"OutputPort-OutputPort-0" -> "OBJECTIVE MECHANISM":"InputPort-Value of OUTER OUTPUT [OutputPort-0]" [label="" color=purple penwidth=1]\n\t"OUTER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
OUTER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tCONTROLLER [label=<
INTERNAL[slope] ControlSignal
OutputPorts
Mechanism:
CONTROLLER
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph "cluster_NESTED COMPOSITION" {\n\t\tgraph [label="NESTED COMPOSITION" overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tTarget [label=<
OutputPort-0
OutputPorts
Mechanism:
Target
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=orange penwidth=3 rank=min shape=plaintext]\n\t\t"INNER INPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER INPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [color=black penwidth=1 shape=diamond]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [arrowhead=none color=black penwidth=1]\n\t\t"MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" -> "INNER OUTPUT":"InputPort-InputPort-0" [color=black penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"OutputPort-LearningSignal" -> "MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label="" color=orange penwidth=1]\n\t\t"NESTED COMPOSITION INPUT" [label=<
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Input_CIM
InputPorts
INPUT_CIM_INNER INPUT_InputPort-0INPUT_CIM_Target_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_INNER INPUT_InputPort-0" -> "INNER INPUT":"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION INPUT":"OutputPort-INPUT_CIM_Target_InputPort-0" -> Target:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"NESTED COMPOSITION OUTPUT" [label=<
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
OutputPorts
Mechanism:
NESTED COMPOSITION Output_CIM
InputPorts
OUTPUT_CIM_INNER OUTPUT_OutputPort-0
> color=red penwidth=1 rank=same shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "NESTED COMPOSITION OUTPUT":"InputPort-OUTPUT_CIM_INNER OUTPUT_OutputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\tComparator [label=<
OUTCOMEMSE
OutputPorts
Mechanism:
Comparator
ParameterPorts
offset
scale
InputPorts
SAMPLETARGET
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> Comparator:"InputPort-SAMPLE" [label="" arrowhead=normal color=orange penwidth=1]\n\t\tTarget:"OutputPort-OutputPort-0" -> Comparator:"InputPort-TARGET" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]" [label=<
error_signalLearningSignal
OutputPorts
Mechanism:
Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]
ParameterPorts
learning_rate
InputPorts
activation_inputactivation_outputerror_signal
> color=orange penwidth=1 rank=min shape=plaintext]\n\t\tComparator:"OutputPort-OUTCOME" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-error_signal" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER INPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_input" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT":"OutputPort-OutputPort-0" -> "Learning Mechanism for MappingProjection from INNER INPUT[OutputPort-0] to INNER OUTPUT[InputPort-0]":"InputPort-activation_output" [label="" arrowhead=normal color=orange penwidth=1]\n\t\t"INNER OUTPUT" [label=<
OutputPort-0
OutputPorts
Mechanism:
INNER OUTPUT
ParameterPorts
intercept
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\t\tlabel="NESTED COMPOSITION"\n\t}\n}' # def test_nested_learning_test_with_user_specified_target_in_outer_composition_using_pathway_notation(self): # ia = ProcessingMechanism(name='INNER INPUT') @@ -353,39 +353,90 @@ def test_of_show_nested_show_cim_and_show_node_structure(self): oa = TransferMechanism(name='oa') ob = TransferMechanism(name='ob') oc = TransferMechanism(name='oc') - ocomp = Composition(name='ocomp', pathways=[oa, icomp, oc]) - ocomp.add_nodes(ob) + ctl_mech = ControlMechanism(name='ctl_mech', + control_signals=[ControlSignal(projections=[(SLOPE, ia)])]) + ocomp = Composition(name='ocomp', pathways=[[ob],[oa, icomp, oc, ctl_mech]]) + # ocomp.add_nodes(ob) + ocm = OptimizationControlMechanism(name='ocm', + agent_rep=ocomp, + control_signals=[ + ControlSignal(projections=[(NOISE, ia)]), + ControlSignal(projections=[(INTERCEPT, ia)]), + ControlSignal(projections=[(SLOPE, oa)]), + ]) + ocomp.add_controller(ocm) + + # ocomp.show_graph(show_cim=True, show_nested=INSET) + gv = ocomp.show_graph(show_nested=False, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' + gv = ocomp.show_graph(show_nested=INSET, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_nested=NESTED, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> ia [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech -> ia [label="" arrowhead=box color=blue penwidth=1]\n\tia -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_cim=True, show_nested=False, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' + gv = ocomp.show_graph(show_cim=True, show_nested=INSET, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=normal color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_cim=True, show_nested=NESTED, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> "icomp INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech -> "icomp CONTROL" [label="" arrowhead=normal color=blue penwidth=1]\n\t"icomp OUTPUT" -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_node_structure=True, show_nested=False, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' + gv = ocomp.show_graph(show_node_structure=True, show_nested=INSET, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_node_structure=True, show_nested=NESTED, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\tia:"OutputPort-RESULT" -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=False, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_ob_InputPort-0INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULTOUTPUT_CIM_oc_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' + gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=INSET, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=normal color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_ob_InputPort-0INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULTOUTPUT_CIM_oc_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [label=<
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=NESTED, output_fmt='source') + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> "icomp INPUT":"InputPort-INPUT_CIM_ia_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_slope" [label="" arrowhead=normal color=blue penwidth=1]\n\t"icomp OUTPUT":"OutputPort-OUTPUT_CIM_ia_RESULT" -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_ob_InputPort-0INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULTOUTPUT_CIM_oc_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_noise" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_intercept" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
InputPorts
INPUT_CIM_ia_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
InputPorts
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [label=<
OUTPUT_CIM_ia_RESULT
OutputPorts
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + + def test_of_show_nested_show_cim_and_show_node_structure_with_singleton_in_outer_comp_added_last(self): + + # Inner Composition + ia = TransferMechanism(name='ia') + icomp = Composition(name='icomp', pathways=[ia]) + + # Outer Composition + oa = TransferMechanism(name='oa') + ob = TransferMechanism(name='ob') + oc = TransferMechanism(name='oc') + ctl_mech = ControlMechanism(name='ctl_mech', + control_signals=[ControlSignal(projections=[(SLOPE, ia)])]) + ocomp = Composition(name='ocomp', pathways=[[oa, icomp, oc, ctl_mech],[ob]]) ocm = OptimizationControlMechanism(name='ocm', agent_rep=ocomp, control_signals=[ ControlSignal(projections=[(NOISE, ia)]), ControlSignal(projections=[(INTERCEPT, ia)]), - ControlSignal(projections=[(SLOPE, ia)]), ControlSignal(projections=[(SLOPE, oa)]), ]) ocomp.add_controller(ocm) + ocomp.show_graph(show_cim=True, show_nested=INSET) gv = ocomp.show_graph(show_nested=False, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' gv = ocomp.show_graph(show_nested=INSET, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_nested=NESTED, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> ia [label="" arrowhead=normal color=black penwidth=1]\n\tia -> oc [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> ia [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech -> ia [label="" arrowhead=box color=blue penwidth=1]\n\tia -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> ia [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_cim=True, show_nested=False, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n}' gv = ocomp.show_graph(show_cim=True, show_nested=INSET, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech -> icomp [label="" arrowhead=normal color=blue penwidth=1]\n\toa -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_cim=True, show_nested=NESTED, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> "icomp INPUT" [label="" color=black penwidth=1]\n\t"icomp OUTPUT" -> oc [label="" color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" color=black penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [color=green penwidth=3 rank=source shape=oval]\n\toa -> "icomp INPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech -> "icomp CONTROL" [label="" arrowhead=normal color=blue penwidth=1]\n\t"icomp OUTPUT" -> oc [label="" arrowhead=normal color=black penwidth=1]\n\toc -> ctl_mech [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t"ocomp INPUT" -> oa [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" -> ob [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\toc -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tob -> "ocomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> "icomp CONTROL" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm -> oa [label="" arrowhead=box color=purple penwidth=1]\n\toc [color=red penwidth=3 rank=max shape=oval]\n\tctl_mech [color=blue penwidth=3 rank=max shape=octagon]\n\tob [color=brown penwidth=3 rank=same shape=oval]\n\tocm [color=purple penwidth=1 rank=min shape=doubleoctagon]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [color=green penwidth=1 rank=same shape=rectangle]\n\t\t"icomp INPUT" -> ia [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [color=purple penwidth=1 rank=same shape=rectangle]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL" -> ia [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [color=red penwidth=1 rank=same shape=rectangle]\n\t\tia -> "icomp OUTPUT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [color=brown penwidth=3 rank=same shape=oval]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_node_structure=True, show_nested=False, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' gv = ocomp.show_graph(show_node_structure=True, show_nested=INSET, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_node_structure=True, show_nested=NESTED, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tia:"OutputPort-RESULT" -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\tia:"OutputPort-RESULT" -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=False, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0INPUT_CIM_ob_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_oc_RESULTOUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=box color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0INPUT_CIM_ob_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_oc_RESULTOUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=box color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n}' gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=INSET, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0INPUT_CIM_ob_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_oc_RESULTOUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp OUTPUT" [label=<
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\ticomp [color=pink penwidth=3 rank=same shape=rectangle]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> icomp [label="" arrowhead=normal color=blue penwidth=1]\n\toa:"OutputPort-RESULT" -> icomp [label="" arrowhead=normal color=black penwidth=1]\n\ticomp -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0INPUT_CIM_ob_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_oc_RESULTOUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> icomp [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [label=<
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' gv = ocomp.show_graph(show_node_structure=True, show_cim=True, show_nested=NESTED, output_fmt='source') - assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> "icomp INPUT":"InputPort-INPUT_CIM_ia_InputPort-0" [label="" color=black penwidth=1]\n\t"icomp OUTPUT":"OutputPort-OUTPUT_CIM_ia_RESULT" -> oc:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_oa_InputPort-0INPUT_CIM_ob_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_oc_RESULTOUTPUT_CIM_ob_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" color=black penwidth=1]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_noise" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_intercept" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[slope] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_slope" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignalia[slope] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
InputPorts
INPUT_CIM_ia_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
InputPorts
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp OUTPUT" [label=<
OUTPUT_CIM_ia_RESULT
OutputPorts
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' + # FIX: NEEDS TO BE CORRECTED ONCE BUG IS FIXED (SEE MESSAGE FOR COMMIT eb61303808ad2a5ba46fdd18d0e583283397915c) + # assert gv == 'digraph ocomp {\n\tgraph [label=ocomp overlap=False rankdir=BT]\n\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\tedge [fontname=arial fontsize=10]\n\toa [label=<
RESULT
OutputPorts
Mechanism:
oa
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=green penwidth=3 rank=source shape=plaintext]\n\toa:"OutputPort-RESULT" -> "icomp INPUT":"InputPort-INPUT_CIM_ia_InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\tctl_mech:"OutputPort-ia[slope] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_slope" [label="" arrowhead=normal color=blue penwidth=1]\n\t"icomp OUTPUT":"OutputPort-OUTPUT_CIM_ia_RESULT" -> oc:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> ctl_mech:"InputPort-OUTCOME" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT" [label=<
INPUT_CIM_ob_InputPort-0INPUT_CIM_oa_InputPort-0
OutputPorts
Mechanism:
ocomp Input_CIM
> color=green penwidth=1 rank=same shape=plaintext]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_ob_InputPort-0" -> ob:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp INPUT":"OutputPort-INPUT_CIM_oa_InputPort-0" -> oa:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t"ocomp OUTPUT" [label=<
Mechanism:
ocomp Output_CIM
InputPorts
OUTPUT_CIM_ob_RESULTOUTPUT_CIM_oc_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\tob:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_ob_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\toc:"OutputPort-RESULT" -> "ocomp OUTPUT":"InputPort-OUTPUT_CIM_oc_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\tocm:"OutputPort-ia[noise] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_noise" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-ia[intercept] ControlSignal" -> "icomp CONTROL":"InputPort-PARAMETER_CIM_ia_intercept" [label="" arrowhead=normal color=purple penwidth=1]\n\tocm:"OutputPort-oa[slope] ControlSignal" -> oa:"ParameterPort-slope" [label="" arrowhead=box color=purple penwidth=1]\n\tob [label=<
RESULT
OutputPorts
Mechanism:
ob
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\toc [label=<
RESULT
OutputPorts
Mechanism:
oc
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=red penwidth=3 rank=max shape=plaintext]\n\tctl_mech [label=<
ia[slope] ControlSignal
OutputPorts
Mechanism:
ctl_mech
InputPorts
OUTCOME
> color=blue penwidth=3 rank=max shape=plaintext]\n\tocm [label=<
ia[noise] ControlSignalia[intercept] ControlSignaloa[slope] ControlSignal
OutputPorts
Mechanism:
ocm
InputPorts
OUTCOMEOUTCOME-1
> color=purple penwidth=1 rank=min shape=plaintext]\n\tsubgraph cluster_icomp {\n\t\tgraph [label=icomp overlap=False rankdir=BT]\n\t\tnode [color=black fontname=arial fontsize=12 penwidth=1 shape=record]\n\t\tedge [fontname=arial fontsize=10]\n\t\t"icomp INPUT" [label=<
INPUT_CIM_ia_InputPort-0
OutputPorts
Mechanism:
icomp Input_CIM
InputPorts
INPUT_CIM_ia_InputPort-0
> color=green penwidth=1 rank=same shape=plaintext]\n\t\t"icomp INPUT":"OutputPort-INPUT_CIM_ia_InputPort-0" -> ia:"InputPort-InputPort-0" [label="" arrowhead=normal color=black penwidth=1]\n\t\t"icomp CONTROL" [label=<
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
OutputPorts
Mechanism:
icomp Parameter_CIM
InputPorts
PARAMETER_CIM_ia_interceptPARAMETER_CIM_ia_noisePARAMETER_CIM_ia_slope
> color=purple penwidth=1 rank=same shape=plaintext]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_intercept" -> ia:"ParameterPort-intercept" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_noise" -> ia:"ParameterPort-noise" [label="" arrowhead=box color=purple penwidth=1]\n\t\t"icomp CONTROL":"OutputPort-PARAMETER_CIM_ia_slope" -> ia:"ParameterPort-slope" [label="" arrowhead=box color=blue penwidth=1]\n\t\t"icomp OUTPUT" [label=<
OUTPUT_CIM_ia_RESULT
OutputPorts
Mechanism:
icomp Output_CIM
InputPorts
OUTPUT_CIM_ia_RESULT
> color=red penwidth=1 rank=same shape=plaintext]\n\t\tia:"OutputPort-RESULT" -> "icomp OUTPUT":"InputPort-OUTPUT_CIM_ia_RESULT" [label="" arrowhead=normal color=black penwidth=1]\n\t\tia [label=<
RESULT
OutputPorts
Mechanism:
ia
ParameterPorts
integration_rate
intercept
noise
slope
InputPorts
InputPort-0
> color=brown penwidth=3 rank=same shape=plaintext]\n\t\tlabel=icomp\n\t}\n}' From 07dd7817b8d2241d82c0ffa12e36d4a001348942 Mon Sep 17 00:00:00 2001 From: Katherine Mantel Date: Wed, 24 Jun 2020 18:45:32 -0400 Subject: [PATCH 19/27] ContentAddressableMemory: fix nonstateful call of .selection_function --- .../components/functions/statefulfunctions/memoryfunctions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psyneulink/core/components/functions/statefulfunctions/memoryfunctions.py b/psyneulink/core/components/functions/statefulfunctions/memoryfunctions.py index b4a73207451..74aefee51e6 100644 --- a/psyneulink/core/components/functions/statefulfunctions/memoryfunctions.py +++ b/psyneulink/core/components/functions/statefulfunctions/memoryfunctions.py @@ -1182,7 +1182,7 @@ def get_memory(self, query_key:tc.any(list, np.ndarray), context=None): distances = [self.distance_function([query_key, list(m)]) for m in _memory[KEYS]] # Get the best-match(es) in memory based on selection_function and return as non-zero value(s) in an array - selection_array = self.selection_function(distances) + selection_array = self.selection_function(distances, context=context) indices_of_selected_items = np.flatnonzero(selection_array) # Single key identified From 75ce32545135dfc48339133e5ef787279f08f9c3 Mon Sep 17 00:00:00 2001 From: Katherine Mantel Date: Thu, 25 Jun 2020 19:27:57 -0400 Subject: [PATCH 20/27] test_projection_specifications: parametrize to identify failing cases more easily --- .../test_projection_specifications.py | 161 +++++++++--------- 1 file changed, 83 insertions(+), 78 deletions(-) diff --git a/tests/projections/test_projection_specifications.py b/tests/projections/test_projection_specifications.py index 8370c3d4c7d..ddead9e6fc9 100644 --- a/tests/projections/test_projection_specifications.py +++ b/tests/projections/test_projection_specifications.py @@ -260,84 +260,89 @@ def test_formats_for_control_specification_for_mechanism_and_function_params(sel assert R.parameter_ports[pnl.GAIN].mod_afferents[0].name in \ 'ControlProjection for RecurrentTransferMechanism-{}[gain]'.format(i) - def test_formats_for_gating_specification_of_input_and_output_ports(self): - - gating_spec_list = [ - pnl.GATING, - pnl.CONTROL, - pnl.GATING_SIGNAL, - pnl.CONTROL_SIGNAL, - pnl.GATING_PROJECTION, - pnl.CONTROL_PROJECTION, - pnl.GatingSignal, - pnl.ControlSignal, - pnl.GatingSignal(), - pnl.ControlSignal(), - pnl.GatingProjection, - "GP_OBJECT", - pnl.GatingMechanism, - pnl.ControlMechanism, - pnl.GatingMechanism(), - pnl.ControlMechanism(), - (0.3, pnl.GATING), - (0.3, pnl.CONTROL), - (0.3, pnl.GATING_SIGNAL), - (0.3, pnl.CONTROL_SIGNAL), - (0.3, pnl.GATING_PROJECTION), - (0.3, pnl.CONTROL_PROJECTION), - (0.3, pnl.GatingSignal), - (0.3, pnl.ControlSignal), - (0.3, pnl.GatingSignal()), - (0.3, pnl.ControlSignal()), - (0.3, pnl.GatingProjection), - (0.3, pnl.ControlProjection), - (0.3, "GP_OBJECT"), - (0.3, pnl.GatingMechanism), - (0.3, pnl.ControlMechanism), - (0.3, pnl.GatingMechanism()), - (0.3, pnl.ControlMechanism()) - ] - for i, gating_tuple in enumerate([j for j in zip(gating_spec_list, reversed(gating_spec_list))]): - G_IN, G_OUT = gating_tuple - - # This shenanigans is to avoid assigning the same instantiated ControlProjection more than once - if G_IN == 'GP_OBJECT': - G_IN = pnl.GatingProjection() - elif isinstance(G_IN, tuple) and G_IN[1] == 'GP_OBJECT': - G_IN = (G_IN[0], pnl.GatingProjection()) - if G_OUT == 'GP_OBJECT': - G_OUT = pnl.GatingProjection() - elif isinstance(G_OUT, tuple) and G_OUT[1] == 'GP_OBJECT': - G_OUT = (G_OUT[0], pnl.GatingProjection()) - - if isinstance(G_IN, tuple): - IN_NAME = G_IN[1] - else: - IN_NAME = G_IN - IN_CONTROL = pnl.CONTROL in repr(IN_NAME).split(".")[-1].upper() - if isinstance(G_OUT, tuple): - OUT_NAME = G_OUT[1] - else: - OUT_NAME = G_OUT - OUT_CONTROL = pnl.CONTROL in repr(OUT_NAME).split(".")[-1].upper() - - T = pnl.TransferMechanism(name='T-GATING-{}'.format(i), - input_ports=[G_IN], - output_ports=[G_OUT]) - - if IN_CONTROL: - assert T.input_ports[0].mod_afferents[0].name in \ - 'ControlProjection for T-GATING-{}[InputPort-0]'.format(i) - else: - assert T.input_ports[0].mod_afferents[0].name in \ - 'GatingProjection for T-GATING-{}[InputPort-0]'.format(i) - - if OUT_CONTROL: - assert T.output_ports[0].mod_afferents[0].name in \ - 'ControlProjection for T-GATING-{}[OutputPort-0]'.format(i) - else: - assert T.output_ports[0].mod_afferents[0].name in \ - 'GatingProjection for T-GATING-{}[OutputPort-0]'.format(i) + gating_spec_list = [ + pnl.GATING, + pnl.CONTROL, + pnl.GATING_SIGNAL, + pnl.CONTROL_SIGNAL, + pnl.GATING_PROJECTION, + pnl.CONTROL_PROJECTION, + pnl.GatingSignal, + pnl.ControlSignal, + pnl.GatingSignal(), + pnl.ControlSignal(), + pnl.GatingProjection, + "GP_OBJECT", + pnl.GatingMechanism, + pnl.ControlMechanism, + pnl.GatingMechanism(), + pnl.ControlMechanism(), + (0.3, pnl.GATING), + (0.3, pnl.CONTROL), + (0.3, pnl.GATING_SIGNAL), + (0.3, pnl.CONTROL_SIGNAL), + (0.3, pnl.GATING_PROJECTION), + (0.3, pnl.CONTROL_PROJECTION), + (0.3, pnl.GatingSignal), + (0.3, pnl.ControlSignal), + (0.3, pnl.GatingSignal()), + (0.3, pnl.ControlSignal()), + (0.3, pnl.GatingProjection), + (0.3, pnl.ControlProjection), + (0.3, "GP_OBJECT"), + (0.3, pnl.GatingMechanism), + (0.3, pnl.ControlMechanism), + (0.3, pnl.GatingMechanism()), + (0.3, pnl.ControlMechanism()) + ] + + @pytest.mark.parametrize( + 'input_port, output_port', + [(inp, outp) for inp, outp in [j for j in zip(gating_spec_list, reversed(gating_spec_list))]] + ) + def test_formats_for_gating_specification_of_input_and_output_ports(self, input_port, output_port): + G_IN, G_OUT = input_port, output_port + + # This shenanigans is to avoid assigning the same instantiated ControlProjection more than once + if G_IN == 'GP_OBJECT': + G_IN = pnl.GatingProjection() + elif isinstance(G_IN, tuple) and G_IN[1] == 'GP_OBJECT': + G_IN = (G_IN[0], pnl.GatingProjection()) + if G_OUT == 'GP_OBJECT': + G_OUT = pnl.GatingProjection() + elif isinstance(G_OUT, tuple) and G_OUT[1] == 'GP_OBJECT': + G_OUT = (G_OUT[0], pnl.GatingProjection()) + + if isinstance(G_IN, tuple): + IN_NAME = G_IN[1] + else: + IN_NAME = G_IN + IN_CONTROL = pnl.CONTROL in repr(IN_NAME).split(".")[-1].upper() + if isinstance(G_OUT, tuple): + OUT_NAME = G_OUT[1] + else: + OUT_NAME = G_OUT + OUT_CONTROL = pnl.CONTROL in repr(OUT_NAME).split(".")[-1].upper() + + T = pnl.TransferMechanism( + name='T-GATING', + input_ports=[G_IN], + output_ports=[G_OUT] + ) + + if IN_CONTROL: + assert T.input_ports[0].mod_afferents[0].name in \ + 'ControlProjection for T-GATING[InputPort-0]' + else: + assert T.input_ports[0].mod_afferents[0].name in \ + 'GatingProjection for T-GATING[InputPort-0]' + + if OUT_CONTROL: + assert T.output_ports[0].mod_afferents[0].name in \ + 'ControlProjection for T-GATING[OutputPort-0]' + else: + assert T.output_ports[0].mod_afferents[0].name in \ + 'GatingProjection for T-GATING[OutputPort-0]' # with pytest.raises(pnl.ProjectionError) as error_text: # T1 = pnl.ProcessingMechanism(name='T1', input_ports=[pnl.ControlMechanism()]) From bdf72182c7de8766278084a10b9446939db9036c Mon Sep 17 00:00:00 2001 From: Dillon Smith Date: Fri, 26 Jun 2020 17:22:18 -0400 Subject: [PATCH 21/27] fix/docs/spacing Added containers to "subclasses" and "related" sections of doc files to enable custom spacing in those sections --- docs/source/Component.rst | 35 ++++++++++--------- docs/source/Composition.rst | 33 +++++++++-------- .../CompositionFunctionApproximator.rst | 11 +++--- docs/source/ControlMechanism.rst | 12 ++++--- docs/source/Mechanism.rst | 26 ++++++++------ docs/source/Mechanisms.rst | 3 +- docs/source/ModulatoryMechanism.rst | 12 ++++--- docs/source/ModulatoryProjection.rst | 14 ++++---- docs/source/ModulatorySignal.rst | 17 ++++----- docs/source/PathwayProjection.rst | 14 ++++---- docs/source/PathwayProjections.rst | 10 +++--- docs/source/Port.rst | 15 ++++---- docs/source/ProcessingMechanism.rst | 14 ++++---- docs/source/Projection.rst | 11 +++--- 14 files changed, 129 insertions(+), 98 deletions(-) diff --git a/docs/source/Component.rst b/docs/source/Component.rst index 5e13237747b..5bdf51ddff2 100644 --- a/docs/source/Component.rst +++ b/docs/source/Component.rst @@ -1,27 +1,30 @@ Component ========= +.. container:: subclasses -*Subclasses:* + *Subclasses* -.. toctree:: - :maxdepth: 1 + .. toctree:: + :maxdepth: 1 - Mechanisms - Projections - Ports - Functions + Mechanisms + Projections + Ports + Functions + | -| -*Related* +.. container:: related -.. toctree:: - :maxdepth: 1 + *Related* + + .. toctree:: + :maxdepth: 1 + + Parameters + Log + Registry + Preferences - Parameters - Log - Registry - Preferences -| .. automodule:: psyneulink.core.components.component :members: :private-members: diff --git a/docs/source/Composition.rst b/docs/source/Composition.rst index fbc1ace6a0d..d1398b6440f 100644 --- a/docs/source/Composition.rst +++ b/docs/source/Composition.rst @@ -1,25 +1,30 @@ Composition =========== -*Subclasses* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - AutodiffComposition - CompositionFunctionApproximator -| -*Related* + .. toctree:: + :maxdepth: 1 -* `NodeRoles ` + AutodiffComposition + CompositionFunctionApproximator + | -.. toctree:: - :maxdepth: 1 +.. container:: related + + *Related* + + * `NodeRoles ` + + .. toctree:: + :maxdepth: 1 + + Pathway + Scheduling + Visualization - Pathway - Scheduling - Visualization -| .. automodule:: psyneulink.core.compositions.composition :members: Composition, NodeRole :private-members: diff --git a/docs/source/CompositionFunctionApproximator.rst b/docs/source/CompositionFunctionApproximator.rst index c1f3d30fd3a..f9392286136 100644 --- a/docs/source/CompositionFunctionApproximator.rst +++ b/docs/source/CompositionFunctionApproximator.rst @@ -1,12 +1,15 @@ CompositionFunctionApproximator =============================== -*Subclasses* -.. toctree:: - :maxdepth: 1 +.. container:: subclasses + + *Subclasses* + + .. toctree:: + :maxdepth: 1 - RegressionCFA + RegressionCFA .. toctree:: :maxdepth: 2 diff --git a/docs/source/ControlMechanism.rst b/docs/source/ControlMechanism.rst index 1fc3c480d91..0f9a2d78552 100644 --- a/docs/source/ControlMechanism.rst +++ b/docs/source/ControlMechanism.rst @@ -3,13 +3,15 @@ ControlMechanism .. _ControlMechanism_Subtypes: -*Subclasses* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - GatingMechanism - OptimzationControlMechanism + .. toctree:: + :maxdepth: 1 + + GatingMechanism + OptimizationControlMechanism .. automodule:: psyneulink.core.components.mechanisms.modulatory.control.controlmechanism :members: diff --git a/docs/source/Mechanism.rst b/docs/source/Mechanism.rst index b5a87cfbf16..1caac05c3bf 100644 --- a/docs/source/Mechanism.rst +++ b/docs/source/Mechanism.rst @@ -1,21 +1,25 @@ Mechanism ========= -*Subclasses:* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - ProcessingMechanism - ModulatoryMechanism -| -*Related* + .. toctree:: + :maxdepth: 1 -.. toctree:: - :maxdepth: 1 + ProcessingMechanism + ModulatoryMechanism + | + +.. container:: related + *Related* + + .. toctree:: + :maxdepth: 1 + + Port - Port -| .. automodule:: psyneulink.core.components.mechanisms.mechanism :members: :private-members: diff --git a/docs/source/Mechanisms.rst b/docs/source/Mechanisms.rst index cdadf40fdf9..dbaede3bd0d 100644 --- a/docs/source/Mechanisms.rst +++ b/docs/source/Mechanisms.rst @@ -4,6 +4,7 @@ Mechanisms .. toctree:: :maxdepth: 3 - *Subclasses:* +.. container:: subclasses + *Subclasses* ProcessingMechanisms ModulatoryMechanisms diff --git a/docs/source/ModulatoryMechanism.rst b/docs/source/ModulatoryMechanism.rst index 6769629bcb2..1529d7324a1 100644 --- a/docs/source/ModulatoryMechanism.rst +++ b/docs/source/ModulatoryMechanism.rst @@ -3,13 +3,15 @@ ModulatoryMechanism .. _ModulatoryMechanism_Subtypes: -*Subclasses* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - ControlMechanism - LearningMechanism + .. toctree:: + :maxdepth: 1 + + ControlMechanism + LearningMechanism .. automodule:: psyneulink.core.components.mechanisms.modulatory.modulatorymechanism :members: diff --git a/docs/source/ModulatoryProjection.rst b/docs/source/ModulatoryProjection.rst index 7d64e6a422a..0f6604ce3a7 100644 --- a/docs/source/ModulatoryProjection.rst +++ b/docs/source/ModulatoryProjection.rst @@ -3,14 +3,16 @@ ModulatoryProjection .. _ModulatoryProjection_Subtypes: -*Subclasses* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - LearningProjection - ControlProjection - GatingProjection + .. toctree:: + :maxdepth: 1 + + LearningProjection + ControlProjection + GatingProjection .. automodule:: psyneulink.core.components.projections.modulatory.modulatoryprojection :members: ModulatoryProjection_Base diff --git a/docs/source/ModulatorySignal.rst b/docs/source/ModulatorySignal.rst index 927885265e5..c36dfe412b9 100644 --- a/docs/source/ModulatorySignal.rst +++ b/docs/source/ModulatorySignal.rst @@ -3,17 +3,18 @@ ModulatorySignal .. _ModulatorySignal_Subtypes: -*Subclasses* +.. container:: subclasses + *Subclasses* -.. toctree:: - :maxdepth: 1 + .. toctree:: + :maxdepth: 1 - LearningSignal - ControlSignal - GatingSignal + LearningSignal + ControlSignal + GatingSignal -.. toctree:: - :maxdepth: 3 + .. toctree:: + :maxdepth: 3 .. automodule:: psyneulink.core.components.ports.modulatorysignals.modulatorysignal :members: diff --git a/docs/source/PathwayProjection.rst b/docs/source/PathwayProjection.rst index c6fe7230894..a574828606c 100644 --- a/docs/source/PathwayProjection.rst +++ b/docs/source/PathwayProjection.rst @@ -1,14 +1,16 @@ PathwayProjection ================= -*Subclasses:* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - MappingProjection - MaskedMappingProjection - AutoAssociativeProjection + .. toctree:: + :maxdepth: 1 + + MappingProjection + MaskedMappingProjection + AutoAssociativeProjection .. automodule:: psyneulink.core.components.projections.pathway.pathwayprojection :members: diff --git a/docs/source/PathwayProjections.rst b/docs/source/PathwayProjections.rst index 4efc9334562..5d4efda98e4 100644 --- a/docs/source/PathwayProjections.rst +++ b/docs/source/PathwayProjections.rst @@ -6,7 +6,9 @@ PathwayProjections .. toctree:: :maxdepth: 1 - *Subclasses:* - MappingProjection - MaskedMappingProjection - AutoAssociativeProjection +.. container:: subclasses + + *Subclasses* + MappingProjection + MaskedMappingProjection + AutoAssociativeProjection diff --git a/docs/source/Port.rst b/docs/source/Port.rst index d8d5adb7784..0849c0c6b6f 100644 --- a/docs/source/Port.rst +++ b/docs/source/Port.rst @@ -2,16 +2,17 @@ Port ==== .. _Port_Subtypes: +.. container:: subclasses -*Subclasses:* + *Subclasses* -.. toctree:: - :maxdepth: 1 + .. toctree:: + :maxdepth: 1 - InputPort - ParameterPort - OutputPort - ModulatorySignal + InputPort + ParameterPort + OutputPort + ModulatorySignal .. automodule:: psyneulink.core.components.ports.port :members: diff --git a/docs/source/ProcessingMechanism.rst b/docs/source/ProcessingMechanism.rst index 85ed6f8c6ab..3805cfe17b0 100644 --- a/docs/source/ProcessingMechanism.rst +++ b/docs/source/ProcessingMechanism.rst @@ -3,14 +3,16 @@ ProcessingMechanism .. _ProcessingMechanism_Subtypes: -*Subclasses* +.. container:: subclasses -.. toctree:: - :maxdepth: 1 + *Subclasses* - TransferMechanism - IntegratorMechanism - ObjectiveMechanism + .. toctree:: + :maxdepth: 1 + + TransferMechanism + IntegratorMechanism + ObjectiveMechanism .. automodule:: psyneulink.core.components.mechanisms.processing.processingmechanism :members: diff --git a/docs/source/Projection.rst b/docs/source/Projection.rst index 7404e3d95e5..ed2c27af34b 100644 --- a/docs/source/Projection.rst +++ b/docs/source/Projection.rst @@ -1,13 +1,14 @@ Projection ========== -*Subclasses:* +.. container:: subclasses + *Subclasses* -.. toctree:: - :maxdepth: 1 + .. toctree:: + :maxdepth: 1 - PathwayProjection - ModulatoryProjection + PathwayProjection + ModulatoryProjection .. automodule:: psyneulink.core.components.projections.projection :members: From 15c49c02050f7bfffed91b70f3f926efa3814882 Mon Sep 17 00:00:00 2001 From: Dillon Smith Date: Fri, 26 Jun 2020 17:47:10 -0400 Subject: [PATCH 22/27] fix/docs/spacing Added space under container directive in "related" section of Mechanism. Lack of space caused "related" not to render. --- docs/source/Mechanism.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/Mechanism.rst b/docs/source/Mechanism.rst index 1caac05c3bf..1d44d02b6bc 100644 --- a/docs/source/Mechanism.rst +++ b/docs/source/Mechanism.rst @@ -13,6 +13,7 @@ Mechanism | .. container:: related + *Related* .. toctree:: From 028721660427cf12e50b89722200140011fa59c2 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Fri, 26 Jun 2020 20:31:05 -0400 Subject: [PATCH 23/27] llvm, functions/GridSearch: Extract mechanism input port values and pass the new vector to cuda_evaluate Signed-off-by: Jan Vesely --- .../core/components/functions/optimizationfunctions.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 7a2f22327d8..86bbf6502d0 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1637,9 +1637,12 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, def _run_cuda_grid(self, ocm, variable, context): assert ocm is ocm.agent_rep.controller + # Compiled evaluate expects the same variable as mech function + new_variable = [ip.parameters.value.get(context) for ip in ocm.input_ports] # Map allocations to values comp_exec = pnlvm.execution.CompExecution(ocm.agent_rep, [context.execution_id]) - ct_alloc, ct_values = comp_exec.cuda_evaluate(variable, self.search_space) + ct_alloc, ct_values = comp_exec.cuda_evaluate(np.atleast_2d(new_variable), + self.search_space) # Reduce array of values to min/max # select_min params are: From 082c1108818c7e95ac7f986f0c938510055a4845 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 28 Jun 2020 17:33:51 -0400 Subject: [PATCH 24/27] llvm/cuda, evaluate: Make sure inputs are always in double precision fp format Fixes failures in predator prey test Signed-off-by: Jan Vesely --- .../core/components/functions/optimizationfunctions.py | 6 ++++-- psyneulink/core/llvm/execution.py | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 86bbf6502d0..0f050dd3759 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1638,10 +1638,12 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, def _run_cuda_grid(self, ocm, variable, context): assert ocm is ocm.agent_rep.controller # Compiled evaluate expects the same variable as mech function - new_variable = [ip.parameters.value.get(context) for ip in ocm.input_ports] + new_variable = [np.asfarray(ip.parameters.value.get(context)) + for ip in ocm.input_ports] + new_variable = np.atleast_2d(new_variable) # Map allocations to values comp_exec = pnlvm.execution.CompExecution(ocm.agent_rep, [context.execution_id]) - ct_alloc, ct_values = comp_exec.cuda_evaluate(np.atleast_2d(new_variable), + ct_alloc, ct_values = comp_exec.cuda_evaluate(new_variable, self.search_space) # Reduce array of values to min/max diff --git a/psyneulink/core/llvm/execution.py b/psyneulink/core/llvm/execution.py index a55f2ff65f6..dcbd3fdba5d 100644 --- a/psyneulink/core/llvm/execution.py +++ b/psyneulink/core/llvm/execution.py @@ -635,8 +635,8 @@ def cuda_evaluate(self, variable, search_space): # all but #2 and #3 are shared ct_param = bin_func.byref_arg_types[0](*ocm._get_evaluate_param_initializer(context)) ct_state = bin_func.byref_arg_types[1](*ocm._get_evaluate_state_initializer(context)) - # FIXME: Make sure the dtype matches _gen_llvm_evaluate_function - allocations = np.atleast_2d([*itertools.product(*search_space)]) + # Make sure the dtype matches _gen_llvm_evaluate_function + allocations = np.asfarray(np.atleast_2d([*itertools.product(*search_space)])) ct_allocations = allocations.ctypes.data_as(ctypes.POINTER(bin_func.byref_arg_types[2] * len(allocations))) out_ty = bin_func.byref_arg_types[3] * len(allocations) ct_in = variable.ctypes.data_as(ctypes.POINTER(bin_func.byref_arg_types[4])) From 1267c52def200420e918e68b1523332fc3f63b94 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 28 Jun 2020 18:42:06 -0400 Subject: [PATCH 25/27] llvm, tests/models: Add large scale variant of predator-prey Signed-off-by: Jan Vesely --- tests/models/test_greedy_agent.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/models/test_greedy_agent.py b/tests/models/test_greedy_agent.py index e292ed29ceb..531f55450cf 100644 --- a/tests/models/test_greedy_agent.py +++ b/tests/models/test_greedy_agent.py @@ -129,10 +129,13 @@ def test_simplified_greedy_agent_random(benchmark, mode): pytest.param('PTXRun', marks=[pytest.mark.llvm, pytest.mark.cuda]), ]) @pytest.mark.parametrize("samples", [[0,10], + pytest.param([a / 10.0 for a in range(0, 101)]), pytest.param([0,3,6,10], marks=pytest.mark.stress), pytest.param([0,2,4,6,8,10], marks=pytest.mark.stress), ], ids=lambda x: len(x)) def test_predator_prey(benchmark, mode, samples): + if len(samples) > 10 and mode not in {"LLVMRun", "Python-PTX"}: + pytest.skip("This test takes too long") # OCM default mode is Python mode, ocm_mode = (mode + "-Python").split('-')[0:2] benchmark.group = "Predator-Prey " + str(len(samples)) From aa2c83222b993328b7cb909f1d8805f4a7a750e2 Mon Sep 17 00:00:00 2001 From: Jan Vesely Date: Sun, 28 Jun 2020 18:59:51 -0400 Subject: [PATCH 26/27] llvm/cuda, functions/GridSearch: Drop unused variable Signed-off-by: Jan Vesely --- psyneulink/core/components/functions/optimizationfunctions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/psyneulink/core/components/functions/optimizationfunctions.py b/psyneulink/core/components/functions/optimizationfunctions.py index 0f050dd3759..6a42ef1e4aa 100644 --- a/psyneulink/core/components/functions/optimizationfunctions.py +++ b/psyneulink/core/components/functions/optimizationfunctions.py @@ -1584,7 +1584,6 @@ def _gen_llvm_function_body(self, ctx, builder, params, state, arg_in, arg_out, opt_count_ptr = builder.alloca(ctx.float_ty) builder.store(opt_count_ptr.type.pointee(0), opt_count_ptr) - replace_ptr = builder.alloca(pnlvm.ir.IntType(1)) # Use NaN here. fcmp_unordered below returns true if one of the # operands is a NaN. This makes sure we always set min_* From 1575aefc2f850aa7e8ff32aba01fd878a3c203df Mon Sep 17 00:00:00 2001 From: Dillon Smith Date: Tue, 30 Jun 2020 09:32:45 -0400 Subject: [PATCH 27/27] fix/showgraph/unused_variables: remove unused variables --- psyneulink/core/compositions/showgraph.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/psyneulink/core/compositions/showgraph.py b/psyneulink/core/compositions/showgraph.py index 5e3bb0d0b32..c0479ce3dc9 100644 --- a/psyneulink/core/compositions/showgraph.py +++ b/psyneulink/core/compositions/showgraph.py @@ -843,7 +843,6 @@ def _assign_processing_components(self, from psyneulink.core.compositions.composition import Composition, NodeRole composition = self.composition - enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None # User passed attrs for nested Composition if isinstance(rcvr, Composition): @@ -1751,7 +1750,6 @@ def _assign_learning_components(self, from psyneulink.core.compositions.composition import NodeRole composition = self.composition - enclosing_g = enclosing_comp._show_graph.G if enclosing_comp else None # Get learning_components, with exception of INPUT (i.e. TARGET) nodes # (i.e., allow TARGET node to continue to be marked as an INPUT node)