Skip to content

Commit

Permalink
Stream-based runner (#269)
Browse files Browse the repository at this point in the history
* Stream-based runner

Additionally, restricted the possible Monad instances that can be
used with the `repeat` function and also generalized `repeat` to work
for both `Step` and `StepS` structures.

* Allow for custom measurements

Measurements that are collected from a collection and then saved
as a case class, will automatically have a parquet schema derived
and as a result will be able to be saved to disk in parquet format.

* Force string identifiers for algorithm and problem

The user is now forced to define a name for the algorithm and the
problem so that they can be identified in the result output. It's not
the best strategy, but it is a valid one until a better scheme is
devised.

* Disallow empty algorithm and problem names

Move empty literals for algorithm and problem names to compile time
errors.

* Adjust the collection after environment changes

Missed acutally using the `onChange` handler in the interpretter.
  • Loading branch information
gpampara authored Feb 28, 2018
1 parent 2e75cc0 commit 8f174d5
Show file tree
Hide file tree
Showing 24 changed files with 229 additions and 61 deletions.
52 changes: 33 additions & 19 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import sbt.Keys._
import sbtrelease.ReleaseStateTransformations._

val scalazVersion = "7.2.7"
val scalazStreamVersion = "0.8.6a"
val spireVersion = "0.13.0"
val monocleVersion = "1.3.2"
val scalacheckVersion = "1.12.6"
val avro4sVersion = "1.8.3"

lazy val buildSettings = Seq(
organization := "net.cilib"
Expand Down Expand Up @@ -161,27 +163,35 @@ lazy val core = project
"eu.timepit" %% "refined" % "0.8.5"
),
wartremoverErrors in (Compile, compile) ++= Seq(
//Wart.Any,
//Wart.Nothing,
Wart.AnyVal,
Wart.ArrayEquals,
Wart.JavaSerializable,
// Wart.Any,
Wart.ExplicitImplicitTypes,
Wart.LeakingSealed,
Wart.StringPlusAny,
Wart.AsInstanceOf,
Wart.IsInstanceOf,
Wart.DefaultArguments,
Wart.ExplicitImplicitTypes,
Wart.FinalCaseClass,
Wart.FinalVal,
Wart.ImplicitConversion,
Wart.ImplicitParameter,
Wart.DefaultArguments,
//Wart.ListOps,
Wart.IsInstanceOf,
Wart.JavaConversions,
Wart.JavaSerializable,
Wart.LeakingSealed,
Wart.MutableDataStructures,
Wart.NonUnitStatements,
Wart.Null,
Wart.Option2Iterable,
Wart.OptionPartial,
//Wart.Overloading,
Wart.Overloading,
Wart.Product,
//Wart.PublicInference,
Wart.Return,
Wart.Serializable,
Wart.StringPlusAny,
Wart.Throw,
Wart.TraversableOps,
Wart.TryPartial,
Wart.Var
)
))
Expand Down Expand Up @@ -267,16 +277,20 @@ lazy val example = project
moduleName := "cilib-example",
libraryDependencies ++= Seq(
"net.cilib" %% "benchmarks" % "0.1.1",
"org.scalaz" %% "scalaz-core" % scalazVersion,
"org.scalaz" %% "scalaz-concurrent" % scalazVersion,
"org.scalaz" %% "scalaz-effect" % scalazVersion,
"org.scalaz.stream" %% "scalaz-stream" % "0.8.6a"
"org.scalaz" %% "scalaz-effect" % scalazVersion
)
))

lazy val exec = project
.dependsOn(core)
.settings(Seq(moduleName := "cilib-exec") ++ cilibSettings)
.settings(cilibSettings ++ Seq(
moduleName := "cilib-exec",
libraryDependencies ++= Seq(
"org.scalaz" %% "scalaz-concurrent" % scalazVersion,
"org.scalaz.stream" %% "scalaz-stream" % scalazStreamVersion,
"com.sksamuel.avro4s" %% "avro4s-core" % avro4sVersion
)
))

lazy val moo = project
.dependsOn(core)
Expand Down Expand Up @@ -308,15 +322,15 @@ lazy val tests = project
))

lazy val io = project
.dependsOn(core)
.dependsOn(core, exec)
.settings(
cilibSettings ++ noPublishSettings ++ Seq(
moduleName := "cilib-io",
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.2",
"org.apache.orc" % "orc-core" % "1.3.3",
"com.sksamuel.avro4s" %% "avro4s-core" % "1.8.0",
"org.apache.parquet" % "parquet-avro" % "1.8.2",
"org.scalaz.stream" %% "scalaz-stream" % "0.8.6a"
"com.sksamuel.avro4s" %% "avro4s-core" % avro4sVersion,
"org.apache.parquet" % "parquet-avro" % "1.9.0",
"org.apache.hadoop" % "hadoop-client" % "2.7.3",
"org.scalaz.stream" %% "scalaz-stream" % scalazStreamVersion
)
))
2 changes: 1 addition & 1 deletion core/src/main/scala/cilib/Constraint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ object ViolationCount {
}
}

case class ConstraintFunction[A](f: NonEmptyList[A] => Double) {
final case class ConstraintFunction[A](f: NonEmptyList[A] => Double) {
def apply(a: NonEmptyList[A]): Double =
f(a)
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cilib/Lenses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cilib

import monocle._

case class Mem[A](b: Position[A], v: Position[A])
final case class Mem[A](b: Position[A], v: Position[A])

@annotation.implicitNotFound(
"A HasMemory instance cannot be found for the provided state type ${S}")
Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cilib/Step.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,6 @@ object StepS {
StepS(M.put(s))
}

def apply[A, S, B](f: S => Step[A, (S, B)]): StepS[A, S, B] =
StepS(StateT[Step[A, ?], S, B](f))

def pointR[A, S, B](a: RVar[B]): StepS[A, S, B] =
StepS(StateT[Step[A, ?], S, B]((s: S) => Step.pointR(a).map((s, _))))

Expand Down
1 change: 1 addition & 0 deletions docs/src/main/tut/usage/gbestpso.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ As the very first step, we need to get the needed imports in scope:
```tut:silent
import cilib._
import cilib.pso._
import cilib.exec._
import eu.timepit.refined.auto._
Expand Down
2 changes: 0 additions & 2 deletions eda/src/main/scala/EDA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ package eda
import scalaz._
import Scalaz._

import spire.implicits._

object EDA {

def eda[M, S, A](
Expand Down
2 changes: 1 addition & 1 deletion example/src/main/scala/cilib/example/GA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,5 @@ object GAExample extends SafeApp {

// Our IO[Unit] that runs at the end of the world
override val runc: IO[Unit] =
putStrLn(Runner.repeat(1000, cullingGA, swarm).run(env).run(RNG.fromTime).toString)
putStrLn(exec.Runner.repeat(1000, cullingGA, swarm).run(env).run(RNG.fromTime).toString)
}
21 changes: 11 additions & 10 deletions example/src/main/scala/cilib/example/GBestPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down Expand Up @@ -30,17 +31,17 @@ object GBestPSO extends SafeApp {
Position.createCollection(PSO.createParticle(x => Entity(Mem(x, x.zeroed), x)))(env.bounds, 20)
val iter = Iteration.sync(gbestPSO)

val problemStream = Runner.staticProblem("spherical", env.eval, RNG.init(123L)).take(1000)

// Our IO[Unit] that runs the algorithm, at the end of the world
override val runc: IO[Unit] = {
val result = Runner.repeat(1000, iter, swarm).run(env).run(RNG.fromTime)

result._2 match {
case -\/(error) =>
throw error

case \/-(value) =>
val positions = value.map(x => Lenses._position.get(x))
putStrLn(positions.toString)
}
val t = Runner.foldStep(env,
RNG.fromTime,
swarm,
Algorithm("gbestPSO", iter),
problemStream,
(x: NonEmptyList[Particle[Mem[Double], Double]]) => RVar.point(x))

putStrLn(t.runLast.unsafePerformSync.toString)
}
}
3 changes: 2 additions & 1 deletion example/src/main/scala/cilib/example/GCPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down Expand Up @@ -45,7 +46,7 @@ object GCPSO extends SafeApp {

val result =
Runner
.repeatS(1000, iter, swarm)
.repeat(1000, iter, swarm)
.run(algParams)
.run(env)
.run(RNG.fromTime)
Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/LBestPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import spire.math.Interval

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

object LBestPSO extends SafeApp {
val env =
Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/Mixed.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import spire.implicits._

import cilib.de._
import cilib.pso._
import cilib.exec._

object Mixed extends SafeApp {

Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/NMPCPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/PCXPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/RandomSearchGA.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import eu.timepit.refined.auto._
import spire.implicits._
import spire.math.Interval
import cilib.ga._
import cilib.exec._

object RandomSearchGA extends SafeApp {
type Ind = Individual[Unit]
Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/UNDXPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down
1 change: 1 addition & 0 deletions example/src/main/scala/cilib/example/VonNeumannPSO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package example

import cilib.pso._
import cilib.pso.Defaults._
import cilib.exec._

import eu.timepit.refined.auto._

Expand Down
18 changes: 18 additions & 0 deletions exec/src/main/scala/cilib/Environment.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cilib
package exec

import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.numeric._

sealed abstract class Env
final case object Unchanged extends Env
final case object Change extends Env

object Env {
def constant: Stream[Env] =
Stream(Unchanged) #::: constant

def frequency[A](n: Int Refined Positive): Stream[Env] =
(constant.take(n - 1) #::: Stream[Env](Change)) #::: frequency(n)
}
11 changes: 11 additions & 0 deletions exec/src/main/scala/cilib/Measurement.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cilib
package exec

import com.sksamuel.avro4s._

final case class Measurement[A: SchemaFor](alg: String,
prob: String,
iteration: Int,
env: Env,
seed: Long,
data: A)
8 changes: 8 additions & 0 deletions exec/src/main/scala/cilib/MonadStep.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package cilib
package exec

import scalaz.Monad

abstract class MonadStep[M[_]: Monad] {
def pointR[A](r: RVar[A]): M[A]
}
Loading

0 comments on commit 8f174d5

Please sign in to comment.