From 227695030456485a69dd18650f15ef41afd77aef Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:28:05 -0500 Subject: [PATCH 1/9] Add simple time calculation for 1 working cycle --- pynars/NARS/Control/Reasoner.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index fb6d1028..24565d01 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -16,7 +16,7 @@ from typing import Callable, List, Tuple, Union import pynars.NARS.Operation as Operation from pynars import Global -from time import time +import time from pynars.NAL.Functions.Tools import project_truth, project from ..GlobalEval import GlobalEval @@ -76,6 +76,7 @@ def input_narsese(self, text, go_cycle: bool = False) -> Tuple[bool, Union[Task, return success, task, task_overflow def cycle(self): + start_cycle_time_in_seconds = time.time() """Everything to do by NARS in a single working cycle""" Global.States.reset() tasks_derived: List[Task] = [] @@ -107,6 +108,12 @@ def cycle(self): thresh_complexity = 20 tasks_derived = [ task for task in tasks_derived if task.term.complexity <= thresh_complexity] + + + # done with cycle + total_cycle_time_in_seconds = time.time() - start_cycle_time_in_seconds + print("cycle took: " + str(total_cycle_time_in_seconds)) + return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) From 624dee08c0e0c6865bcaa4c47d04dd049bbf6f68 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 18 Jan 2024 16:59:13 -0500 Subject: [PATCH 2/9] store cycle metrics in reasoner; calculate cycles per second --- pynars/NARS/Control/Reasoner.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index 24565d01..d8d34b77 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -50,6 +50,12 @@ def __init__(self, n_memory, capacity, config='./config.json', nal_rules={1, 2, self.u_top_level_attention = 0.5 + # metrics + self.cycles_per_second_timer = 0 + self.cycles_per_second_counter = 0 + self.cycles_per_second = 0 + self.last_cycle_time = 0 + def reset(self): self.memory.reset() self.overall_experience.reset() @@ -111,8 +117,18 @@ def cycle(self): # done with cycle + + # record some metrics total_cycle_time_in_seconds = time.time() - start_cycle_time_in_seconds - print("cycle took: " + str(total_cycle_time_in_seconds)) + self.last_cycle_time = total_cycle_time_in_seconds + self.cycles_per_second_timer += total_cycle_time_in_seconds + self.cycles_per_second_counter += 1 + if self.cycles_per_second_timer > 1: + # 1 second has passed + self.cycles_per_second = self.cycles_per_second_counter # store the result + self.cycles_per_second_timer = 0 # reset the timer + self.cycles_per_second_counter = 0 # reset the counter + return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) From 545ab0332288b511d6592bd465fd8660ea1bdd5b Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:11:47 -0500 Subject: [PATCH 3/9] Add a ConsolePlus command to display cycles per second ("/cycles") --- pynars/ConsolePlus.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index 9f5b4ffb..b6ff2f26 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -220,6 +220,12 @@ def toggle_silent() -> None: else "closed" }.''') +@cmd_register('cycles') +def cycles(*args: List[str]) -> None: + '''Format: volume [volume:int 0~100] + Set the Output Volume of the console to control its output (same as OpenNARS)''' + current_NARS_interface.print_output( + type=PrintType.INFO, content=f'''Cycles per second is {current_NARS_interface.reasoner.cycles_per_second}.''') @cmd_register(('volume'), (int, 100)) def volume(vol:int) -> None: From 799b9d9690ef286ad6c38f4e430f8498b2e4222d Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Tue, 23 Jan 2024 17:37:36 -0500 Subject: [PATCH 4/9] Extend metric output on ConsolePlus. Update comments; remove whitespace. --- pynars/ConsolePlus.py | 5 ++--- pynars/NARS/Control/Reasoner.py | 13 +++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index b6ff2f26..0b62ec82 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -222,10 +222,9 @@ def toggle_silent() -> None: @cmd_register('cycles') def cycles(*args: List[str]) -> None: - '''Format: volume [volume:int 0~100] - Set the Output Volume of the console to control its output (same as OpenNARS)''' + '''Prints the "average cycles per second" metric''' current_NARS_interface.print_output( - type=PrintType.INFO, content=f'''Cycles per second is {current_NARS_interface.reasoner.cycles_per_second}.''') + type=PrintType.INFO, content=f'''Cycles per second is {current_NARS_interface.reasoner.cycles_per_second}. Last cycle took {current_NARS_interface.reasoner.last_cycle_duration:f} seconds.''') @cmd_register(('volume'), (int, 100)) def volume(vol:int) -> None: diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index d8d34b77..d2e3e56f 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -54,7 +54,7 @@ def __init__(self, n_memory, capacity, config='./config.json', nal_rules={1, 2, self.cycles_per_second_timer = 0 self.cycles_per_second_counter = 0 self.cycles_per_second = 0 - self.last_cycle_time = 0 + self.last_cycle_duration = 0 def reset(self): self.memory.reset() @@ -115,13 +115,11 @@ def cycle(self): tasks_derived = [ task for task in tasks_derived if task.term.complexity <= thresh_complexity] - - # done with cycle - + """done with cycle""" # record some metrics - total_cycle_time_in_seconds = time.time() - start_cycle_time_in_seconds - self.last_cycle_time = total_cycle_time_in_seconds - self.cycles_per_second_timer += total_cycle_time_in_seconds + total_cycle_duration_in_seconds = time.time() - start_cycle_time_in_seconds + self.last_cycle_duration = total_cycle_duration_in_seconds + self.cycles_per_second_timer += total_cycle_duration_in_seconds self.cycles_per_second_counter += 1 if self.cycles_per_second_timer > 1: # 1 second has passed @@ -129,7 +127,6 @@ def cycle(self): self.cycles_per_second_timer = 0 # reset the timer self.cycles_per_second_counter = 0 # reset the counter - return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) From 2b2fd7046e7ba0db15105bd40debb4eac8375d05 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:29:52 -0500 Subject: [PATCH 5/9] Update Reasoner.py --- pynars/NARS/Control/Reasoner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index d2e3e56f..dd8af2d1 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -16,7 +16,7 @@ from typing import Callable, List, Tuple, Union import pynars.NARS.Operation as Operation from pynars import Global -import time +from time import time from pynars.NAL.Functions.Tools import project_truth, project from ..GlobalEval import GlobalEval @@ -82,7 +82,7 @@ def input_narsese(self, text, go_cycle: bool = False) -> Tuple[bool, Union[Task, return success, task, task_overflow def cycle(self): - start_cycle_time_in_seconds = time.time() + start_cycle_time_in_seconds = time() """Everything to do by NARS in a single working cycle""" Global.States.reset() tasks_derived: List[Task] = [] @@ -117,7 +117,7 @@ def cycle(self): """done with cycle""" # record some metrics - total_cycle_duration_in_seconds = time.time() - start_cycle_time_in_seconds + total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds self.last_cycle_duration = total_cycle_duration_in_seconds self.cycles_per_second_timer += total_cycle_duration_in_seconds self.cycles_per_second_counter += 1 From 83e82754b76ced788eb750a25200fb2d803ec497 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 1 May 2024 22:32:07 -0400 Subject: [PATCH 6/9] keep a running average of cycle duration --- pynars/Config.py | 3 +++ pynars/ConsolePlus.py | 5 +++-- pynars/NARS/Control/Reasoner.py | 34 +++++++++++++++++++-------------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/pynars/Config.py b/pynars/Config.py index 22cb8f78..9235f8d3 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -84,6 +84,9 @@ class Config: maximum_evidental_base_length = 20000 + # cycle metrics + cycle_durations_window_length = 100 + @classmethod def check(cls): '''Check if each parameter is valid''' diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index 0b62ec82..204cab57 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -223,8 +223,9 @@ def toggle_silent() -> None: @cmd_register('cycles') def cycles(*args: List[str]) -> None: '''Prints the "average cycles per second" metric''' - current_NARS_interface.print_output( - type=PrintType.INFO, content=f'''Cycles per second is {current_NARS_interface.reasoner.cycles_per_second}. Last cycle took {current_NARS_interface.reasoner.last_cycle_duration:f} seconds.''') + if(len(current_NARS_interface.reasoner.cycles_durations_window) == 0): current_NARS_interface.print_output(type=PrintType.INFO, content="No cycles have been run yet.") + else: current_NARS_interface.print_output( + type=PrintType.INFO, content=f'''The average cycles per second is {1 / current_NARS_interface.reasoner.avg_cycle_duration} based on the last {len(current_NARS_interface.reasoner.cycles_durations_window)} cycles. Last cycle took {current_NARS_interface.reasoner.last_cycle_duration:.32f} seconds.''') @cmd_register(('volume'), (int, 100)) def volume(vol:int) -> None: diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index dd8af2d1..294be5e7 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -21,7 +21,6 @@ from ..GlobalEval import GlobalEval - class Reasoner: def __init__(self, n_memory, capacity, config='./config.json', nal_rules={1, 2, 3, 4, 5, 6, 7, 8, 9}) -> None: @@ -51,10 +50,10 @@ def __init__(self, n_memory, capacity, config='./config.json', nal_rules={1, 2, self.u_top_level_attention = 0.5 # metrics - self.cycles_per_second_timer = 0 - self.cycles_per_second_counter = 0 - self.cycles_per_second = 0 self.last_cycle_duration = 0 + self.cycles_durations_window = [] + self.cycles_duration_window_sum = 0 + self.avg_cycle_duration = 0 def reset(self): self.memory.reset() @@ -116,20 +115,27 @@ def cycle(self): task for task in tasks_derived if task.term.complexity <= thresh_complexity] """done with cycle""" - # record some metrics - total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds - self.last_cycle_duration = total_cycle_duration_in_seconds - self.cycles_per_second_timer += total_cycle_duration_in_seconds - self.cycles_per_second_counter += 1 - if self.cycles_per_second_timer > 1: - # 1 second has passed - self.cycles_per_second = self.cycles_per_second_counter # store the result - self.cycles_per_second_timer = 0 # reset the timer - self.cycles_per_second_counter = 0 # reset the counter + self.do_cycle_metrics(start_cycle_time_in_seconds) return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) + def do_cycle_metrics(self, start_cycle_time_in_seconds: float): + # record some metrics + total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds + self.last_cycle_duration = total_cycle_duration_in_seconds # store the cycle duration + # put it in with the others to find the avg duration + self.cycles_durations_window.append(total_cycle_duration_in_seconds) + self.cycles_duration_window_sum += total_cycle_duration_in_seconds + + # we only want to keep track of a certain number of cycles, so remove old cycles + if len(self.cycles_durations_window) > Config.Config.cycle_durations_window_length: + + self.cycles_duration_window_sum -= self.cycles_durations_window[0] + self.cycles_durations_window.pop(0) + + self.avg_cycle_duration = self.cycles_duration_window_sum / len(self.cycles_durations_window) # avg seconds per 1 cycle + def consider(self, tasks_derived: List[Task]): """ Consider a Concept in the Memory From 7c7b8c470abff00efb519912652854f04ae8c916 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Wed, 1 May 2024 22:33:44 -0400 Subject: [PATCH 7/9] Move function to bottom of file, since it will rarely be touched compared to the other functions --- pynars/NARS/Control/Reasoner.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index 294be5e7..ec9ae583 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -120,21 +120,6 @@ def cycle(self): return tasks_derived, judgement_revised, goal_revised, answers_question, answers_quest, ( task_operation_return, task_executed) - def do_cycle_metrics(self, start_cycle_time_in_seconds: float): - # record some metrics - total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds - self.last_cycle_duration = total_cycle_duration_in_seconds # store the cycle duration - # put it in with the others to find the avg duration - self.cycles_durations_window.append(total_cycle_duration_in_seconds) - self.cycles_duration_window_sum += total_cycle_duration_in_seconds - - # we only want to keep track of a certain number of cycles, so remove old cycles - if len(self.cycles_durations_window) > Config.Config.cycle_durations_window_length: - - self.cycles_duration_window_sum -= self.cycles_durations_window[0] - self.cycles_durations_window.pop(0) - - self.avg_cycle_duration = self.cycles_duration_window_sum / len(self.cycles_durations_window) # avg seconds per 1 cycle def consider(self, tasks_derived: List[Task]): """ @@ -298,3 +283,20 @@ def register_operator(self, name_operator: str, callback: Callable): Operation.register(op, callback) return op return None + + def do_cycle_metrics(self, start_cycle_time_in_seconds: float): + # record some metrics + total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds + self.last_cycle_duration = total_cycle_duration_in_seconds # store the cycle duration + # put it in with the others to find the avg duration + self.cycles_durations_window.append(total_cycle_duration_in_seconds) + self.cycles_duration_window_sum += total_cycle_duration_in_seconds + + # we only want to keep track of a certain number of cycles, so remove old cycles + if len(self.cycles_durations_window) > Config.Config.cycle_durations_window_length: + + self.cycles_duration_window_sum -= self.cycles_durations_window[0] + self.cycles_durations_window.pop(0) + + self.avg_cycle_duration = self.cycles_duration_window_sum / len(self.cycles_durations_window) # avg seconds per 1 cycle + From eec912c999e40e884e27231e4d1020d3438b6e81 Mon Sep 17 00:00:00 2001 From: Maxim Tarasov Date: Fri, 3 May 2024 10:41:34 -0700 Subject: [PATCH 8/9] calculate running mean of cycle duration --- pynars/ConsolePlus.py | 4 ++-- pynars/NARS/Control/Reasoner.py | 18 ++++-------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/pynars/ConsolePlus.py b/pynars/ConsolePlus.py index 204cab57..67bea909 100644 --- a/pynars/ConsolePlus.py +++ b/pynars/ConsolePlus.py @@ -223,9 +223,9 @@ def toggle_silent() -> None: @cmd_register('cycles') def cycles(*args: List[str]) -> None: '''Prints the "average cycles per second" metric''' - if(len(current_NARS_interface.reasoner.cycles_durations_window) == 0): current_NARS_interface.print_output(type=PrintType.INFO, content="No cycles have been run yet.") + if(current_NARS_interface.reasoner.cycles_count == 0): current_NARS_interface.print_output(type=PrintType.INFO, content="No cycles have been run yet.") else: current_NARS_interface.print_output( - type=PrintType.INFO, content=f'''The average cycles per second is {1 / current_NARS_interface.reasoner.avg_cycle_duration} based on the last {len(current_NARS_interface.reasoner.cycles_durations_window)} cycles. Last cycle took {current_NARS_interface.reasoner.last_cycle_duration:.32f} seconds.''') + type=PrintType.INFO, content=f'''The average cycles per second is {int(1 // current_NARS_interface.reasoner.avg_cycle_duration)} based on the last {current_NARS_interface.reasoner.cycles_count} cycles. Last cycle took {current_NARS_interface.reasoner.last_cycle_duration:.6f} seconds.''') @cmd_register(('volume'), (int, 100)) def volume(vol:int) -> None: diff --git a/pynars/NARS/Control/Reasoner.py b/pynars/NARS/Control/Reasoner.py index ec9ae583..7d535756 100644 --- a/pynars/NARS/Control/Reasoner.py +++ b/pynars/NARS/Control/Reasoner.py @@ -50,9 +50,8 @@ def __init__(self, n_memory, capacity, config='./config.json', nal_rules={1, 2, self.u_top_level_attention = 0.5 # metrics + self.cycles_count = 0 self.last_cycle_duration = 0 - self.cycles_durations_window = [] - self.cycles_duration_window_sum = 0 self.avg_cycle_duration = 0 def reset(self): @@ -288,15 +287,6 @@ def do_cycle_metrics(self, start_cycle_time_in_seconds: float): # record some metrics total_cycle_duration_in_seconds = time() - start_cycle_time_in_seconds self.last_cycle_duration = total_cycle_duration_in_seconds # store the cycle duration - # put it in with the others to find the avg duration - self.cycles_durations_window.append(total_cycle_duration_in_seconds) - self.cycles_duration_window_sum += total_cycle_duration_in_seconds - - # we only want to keep track of a certain number of cycles, so remove old cycles - if len(self.cycles_durations_window) > Config.Config.cycle_durations_window_length: - - self.cycles_duration_window_sum -= self.cycles_durations_window[0] - self.cycles_durations_window.pop(0) - - self.avg_cycle_duration = self.cycles_duration_window_sum / len(self.cycles_durations_window) # avg seconds per 1 cycle - + # calculate average + self.cycles_count += 1 + self.avg_cycle_duration += (self.last_cycle_duration - self.avg_cycle_duration) / self.cycles_count From f0a41d40123f8f797db0801aa957250251e9f5d0 Mon Sep 17 00:00:00 2001 From: ccrock4t <15344554+ccrock4t@users.noreply.github.com> Date: Fri, 3 May 2024 19:43:27 -0400 Subject: [PATCH 9/9] Revert config --- pynars/Config.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pynars/Config.py b/pynars/Config.py index 9235f8d3..22cb8f78 100644 --- a/pynars/Config.py +++ b/pynars/Config.py @@ -84,9 +84,6 @@ class Config: maximum_evidental_base_length = 20000 - # cycle metrics - cycle_durations_window_length = 100 - @classmethod def check(cls): '''Check if each parameter is valid'''