MilesCranmer commited on
Commit
121e6ac
1 Parent(s): 13409d1

Allow for more populations than processes

Browse files
Files changed (2) hide show
  1. julia/sr.jl +8 -9
  2. pysr/sr.py +5 -0
julia/sr.jl CHANGED
@@ -748,28 +748,27 @@ function fullRun(niterations::Integer;
748
  )
749
  # 1. Start a population on every process
750
  allPops = Future[]
751
- bestSubPops = [Population(1) for j=1:nprocs]
752
  hallOfFame = HallOfFame()
753
 
754
- for i=1:nprocs
755
- npop=300
756
- future = @spawnat :any Population(npop, 3)
757
  push!(allPops, future)
758
  end
759
 
760
  # # 2. Start the cycle on every process:
761
- for i=1:nprocs
762
- allPops[i] = @spawnat :any run(fetch(allPops[i]), ncyclesperiteration, verbosity=verbosity)
763
  end
764
  println("Started!")
765
- cycles_complete = nprocs * niterations
766
 
767
  last_print_time = time()
768
  num_equations = 0.0
769
  print_every_n_seconds = 1
770
 
771
  while cycles_complete > 0
772
- for i=1:nprocs
773
  if isready(allPops[i])
774
  cur_pop = fetch(allPops[i])
775
  bestSubPops[i] = bestSubPop(cur_pop, topn=topn)
@@ -828,7 +827,7 @@ function fullRun(niterations::Integer;
828
  end
829
  end
830
 
831
- allPops[i] = @spawnat :any let
832
  tmp_pop = run(cur_pop, ncyclesperiteration, verbosity=verbosity)
833
  for j=1:tmp_pop.n
834
  if rand() < 0.1
 
748
  )
749
  # 1. Start a population on every process
750
  allPops = Future[]
751
+ bestSubPops = [Population(1) for j=1:npopulations]
752
  hallOfFame = HallOfFame()
753
 
754
+ for i=1:npopulations
755
+ future = @spawn Population(npop, 3)
 
756
  push!(allPops, future)
757
  end
758
 
759
  # # 2. Start the cycle on every process:
760
+ @sync for i=1:npopulations
761
+ @async allPops[i] = @spawn run(fetch(allPops[i]), ncyclesperiteration, verbosity=verbosity)
762
  end
763
  println("Started!")
764
+ cycles_complete = npopulations * niterations
765
 
766
  last_print_time = time()
767
  num_equations = 0.0
768
  print_every_n_seconds = 1
769
 
770
  while cycles_complete > 0
771
+ for i=1:npopulations
772
  if isready(allPops[i])
773
  cur_pop = fetch(allPops[i])
774
  bestSubPops[i] = bestSubPop(cur_pop, topn=topn)
 
827
  end
828
  end
829
 
830
+ @async allPops[i] = @spawn let
831
  tmp_pop = run(cur_pop, ncyclesperiteration, verbosity=verbosity)
832
  for j=1:tmp_pop.n
833
  if rand() < 0.1
pysr/sr.py CHANGED
@@ -7,6 +7,7 @@ import pandas as pd
7
 
8
  def pysr(X=None, y=None, weights=None,
9
  procs=4,
 
10
  niterations=100,
11
  ncyclesperiteration=300,
12
  binary_operators=["plus", "mult"],
@@ -49,6 +50,7 @@ def pysr(X=None, y=None, weights=None,
49
  :param weights: np.ndarray, 1D array. Each row is how to weight the
50
  mean-square-error loss on weights.
51
  :param procs: int, Number of processes (=number of populations running).
 
52
  :param niterations: int, Number of iterations of the algorithm to run. The best
53
  equations are printed, and migrate between populations, at the
54
  end of each.
@@ -108,6 +110,8 @@ def pysr(X=None, y=None, weights=None,
108
  assert len(weights.shape) == 1
109
  assert X.shape[0] == weights.shape[0]
110
 
 
 
111
 
112
  rand_string = f'{"".join([str(np.random.rand())[2] for i in range(20)])}'
113
 
@@ -162,6 +166,7 @@ const fractionReplacedHof = {fractionReplacedHof}f0
162
  const shouldOptimizeConstants = {'true' if shouldOptimizeConstants else 'false'}
163
  const hofFile = "{equation_file}"
164
  const nprocs = {procs:d}
 
165
  const nrestarts = {nrestarts:d}
166
  const perturbationFactor = {perturbationFactor:f}f0
167
  const annealing = {"true" if annealing else "false"}
 
7
 
8
  def pysr(X=None, y=None, weights=None,
9
  procs=4,
10
+ populations=None,
11
  niterations=100,
12
  ncyclesperiteration=300,
13
  binary_operators=["plus", "mult"],
 
50
  :param weights: np.ndarray, 1D array. Each row is how to weight the
51
  mean-square-error loss on weights.
52
  :param procs: int, Number of processes (=number of populations running).
53
+ :param populations: int, Number of populations running; by default=procs.
54
  :param niterations: int, Number of iterations of the algorithm to run. The best
55
  equations are printed, and migrate between populations, at the
56
  end of each.
 
110
  assert len(weights.shape) == 1
111
  assert X.shape[0] == weights.shape[0]
112
 
113
+ if populations is None:
114
+ populations = procs
115
 
116
  rand_string = f'{"".join([str(np.random.rand())[2] for i in range(20)])}'
117
 
 
166
  const shouldOptimizeConstants = {'true' if shouldOptimizeConstants else 'false'}
167
  const hofFile = "{equation_file}"
168
  const nprocs = {procs:d}
169
+ const npopulations = {populations:d}
170
  const nrestarts = {nrestarts:d}
171
  const perturbationFactor = {perturbationFactor:f}f0
172
  const annealing = {"true" if annealing else "false"}