Skip to content

Commit

Permalink
Separated operations and buffers from items agents. Added specializat…
Browse files Browse the repository at this point in the history
…ion on Scala side.

This change allows to have multiple different buffers used by a sorting
algorithm without the need to implement a specialized items agent for
it. Items buffers are grouped in flexible sort specific setups.
  • Loading branch information
tarsa committed Dec 17, 2017
1 parent 623a8eb commit 34ff7f4
Show file tree
Hide file tree
Showing 126 changed files with 3,942 additions and 2,817 deletions.
6 changes: 2 additions & 4 deletions BACKLOG.md
@@ -1,14 +1,11 @@
Backlog:

* update README.md
* convert native C++ sorts to use items agents
* replace asserts with matchers in tests
* add ActorRef wrappers with typed `tell` forwarders
* remove native C++ items handlers when we are left with items agents only
* make witness classes for native C++ items agents instead of useless
inheritance of empty methods
* use specialization in Scala items agents
* implement guards in generated native C++ headers (eg enums)
* decide on int8_t or uint8_t in native C++ number codecs and buffered I/O
* implement missing unit tests
* reorganize project structure to make more sense
* improve web-based GUI
Expand All @@ -18,3 +15,4 @@ Backlog:
* add support for LLVM/ Clang (that could e.g. make tests run quicker)
* change license to Apache 2.0
* use lenses from https://github.com/adamw/quicklens
* use ScalaCheck or ScalaProps for property-based testing
Expand Up @@ -19,7 +19,7 @@
*/
package pl.tarsa.sortalgobox.main

import pl.tarsa.sortalgobox.core.common.MeasuredSortAlgorithm
import pl.tarsa.sortalgobox.core.common.SelfMeasuredSortAlgorithm
import pl.tarsa.sortalgobox.core.{Benchmark, NativeBenchmark}
import pl.tarsa.sortalgobox.random.Mwc64x
import pl.tarsa.sortalgobox.sorts.jre._
Expand All @@ -34,12 +34,12 @@ import scala.concurrent.duration.FiniteDuration
object BenchmarksConfigurations {
val plainSorts: List[(String, AnyRef)] =
List(
"BitonicSort" -> new BitonicSort,
"BitonicSort" -> BitonicSort,
"SequentialArraysSort" -> SequentialArraysSort.intSort,
"ParallelArraySort" -> ParallelArraysSort.intSort
)

val measuredSorts: List[(String, MeasuredSortAlgorithm[Int])] =
val measuredSorts: List[(String, SelfMeasuredSortAlgorithm[Int])] =
List(
"CpuBitonicSort" -> CpuBitonicSort,
"GpuBitonicSort" -> GpuBitonicSort,
Expand Down Expand Up @@ -72,7 +72,7 @@ object BenchmarksConfigurations {

val benchmarks: List[Benchmark] = {
nativeBenchmarks ::: measuredSorts.map {
case (sortName: String, sort: MeasuredSortAlgorithm[Int]) =>
case (sortName: String, sort: SelfMeasuredSortAlgorithm[Int]) =>
new Benchmark {
override def forSize(itemsNumber: Int,
validate: Boolean,
Expand Down
Expand Up @@ -19,29 +19,33 @@
*/
package pl.tarsa.sortalgobox.main

import pl.tarsa.sortalgobox.core.common.agents.implementations.ComparingIntArrayItemsAgent
import pl.tarsa.sortalgobox.core.common.items.agents.{
ItemsAgent,
PlainItemsAgent
}
import pl.tarsa.sortalgobox.core.common.{
ComparisonSortAlgorithm,
ComparableItemsAgentSortAlgorithm,
GenericIntSortAlgorithm,
MeasuredSortAlgorithm
SelfMeasuredSortAlgorithm
}

import scala.concurrent.duration.Duration

object MeasuringIntSortAlgorithmWrapper {
def apply(plainSortAlgorithm: AnyRef): MeasuredSortAlgorithm[Int] = {
def apply(plainSortAlgorithm: AnyRef): SelfMeasuredSortAlgorithm[Int] = {
plainSortAlgorithm match {
case sortAlgorithm: GenericIntSortAlgorithm =>
wrap(sortAlgorithm)
case sortAlgorithm: ComparisonSortAlgorithm =>
case sortAlgorithm: ComparableItemsAgentSortAlgorithm =>
wrap { intArray: Array[Int] =>
val itemsAgent = new ComparingIntArrayItemsAgent(intArray)
sortAlgorithm.sort(itemsAgent)
val itemsAgent: ItemsAgent = PlainItemsAgent
val setup = sortAlgorithm.setupSort(intArray)
sortAlgorithm.sortExplicit(setup, itemsAgent)
}
}
}

def wrap(doSorting: (Array[Int]) => Unit): MeasuredSortAlgorithm[Int] = {
def wrap(doSorting: Array[Int] => Unit): SelfMeasuredSortAlgorithm[Int] = {
(array: Array[Int]) =>
val startTime = System.nanoTime()
doSorting(array)
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Expand Up @@ -60,7 +60,7 @@ lazy val deps =
"com.typesafe.akka" %% "akka-actor" % Versions.akka,
"com.typesafe.akka" %% "akka-http" % Versions.akkaHttp,
"com.jsuereth" %% "scala-arm" % "2.0",
"commons-io" % "commons-io" % "2.5",
"commons-io" % "commons-io" % "2.6",
"org.apache.commons" % "commons-math3" % "3.6.1",
"org.scalafx" %% "scalafx" % Versions.scalaFx,
// test libraries
Expand Down
3 changes: 1 addition & 2 deletions common/main_rsrc/pl/tarsa/sortalgobox/license_header
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Piotr Tarsa ( http://github.com/tarsa )
* Copyright (C) 2015 - 2017 Piotr Tarsa ( http://github.com/tarsa )
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
Expand All @@ -16,5 +16,4 @@
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
*/
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015, 2016 Piotr Tarsa ( http://github.com/tarsa )
* Copyright (C) 2015 - 2017 Piotr Tarsa ( http://github.com/tarsa )
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
Expand All @@ -21,7 +21,8 @@ package pl.tarsa.sortalgobox.common.crossverify

object TrackingEnums {
object ActionTypes extends Enumeration {
type ActionType = Value
val Size0, Get0, Set0, Copy0, Swap0, Compare, Compare0 = Value
type Action = Value
val Size, Get, Set, Swap, ItemBitsSize, AsLong, GetSlice, CompareEq,
CompareGt, CompareGte, CompareLt, CompareLte = Value
}
}
Expand Up @@ -21,7 +21,7 @@ package pl.tarsa.sortalgobox.tests

import java.util.concurrent.{Executors, TimeUnit}

import org.scalatest.{FlatSpec, Inside, MustMatchers}
import org.scalatest.{AppendedClues, FlatSpec, Inside, Inspectors, MustMatchers}

import scala.concurrent.duration.Duration
import scala.concurrent.{
Expand All @@ -30,25 +30,33 @@ import scala.concurrent.{
ExecutionContextExecutorService,
Future
}
import scala.reflect.ClassTag
import scala.reflect.runtime.universe._

abstract class CommonUnitSpecBase
extends FlatSpec
with MustMatchers
with Inside {

type TestException = LightException
with Inside
with Inspectors
with AppendedClues {

System.setProperty("uniqueLibraryNames", "true")

val `have full code coverage` = "have full code coverage"

def typeBehavior[T](implicit classTag: ClassTag[T]): Unit =
behavior of classTag.runtimeClass.getSimpleName
type TestException = LightException

def testException: Exception =
LightException(s"boom in $suiteName")

//noinspection UnitMethodIsParameterless
// TODO add parentheses
def typeBehavior[T: TypeTag]: Unit =
behavior of typeName[T]

def typeName[T: TypeTag]: String =
typeOf[T].typeSymbol.toString

val `have full code coverage` = "have full code coverage"

// TODO remove and mix in Futures trait instead
implicit class InstantFuture[T](future: Future[T]) {
def readyNow(): Future[T] = Await.ready(future, Duration.Inf)

Expand Down

This file was deleted.

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Piotr Tarsa ( http://github.com/tarsa )
* Copyright (C) 2015 - 2017 Piotr Tarsa ( http://github.com/tarsa )
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
Expand All @@ -16,20 +16,21 @@
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
*/
package pl.tarsa.sortalgobox.core.common

import scala.reflect.ClassTag

abstract class GenericSortAlgorithm[T: ClassTag](doSorting: (Array[T] => Unit))
extends (Array[T] => Unit) {

override def apply(array: Array[T]): Unit = doSorting(array)
sealed abstract class GenericSortAlgorithm[T: ClassTag](
doSorting: Array[T] => Unit)
extends (Array[T] => Unit) {

override def apply(array: Array[T]): Unit =
doSorting(array)
}

case class GenericIntSortAlgorithm(doSorting: (Array[Int] => Unit))
extends GenericSortAlgorithm[Int](doSorting)
case class GenericIntSortAlgorithm(doSorting: Array[Int] => Unit)
extends GenericSortAlgorithm[Int](doSorting)

case class GenericLongSortAlgorithm(doSorting: (Array[Long] => Unit))
extends GenericSortAlgorithm[Long](doSorting)
case class GenericLongSortAlgorithm(doSorting: Array[Long] => Unit)
extends GenericSortAlgorithm[Long](doSorting)
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2015 - 2017 Piotr Tarsa ( http://github.com/tarsa )
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
package pl.tarsa.sortalgobox.core.common

import pl.tarsa.sortalgobox.core.common.Specialization.{Group => Grp}
import pl.tarsa.sortalgobox.core.common.items.agents.ItemsAgent
import pl.tarsa.sortalgobox.core.common.items.buffers.NumericItemsBuffer.Evidence

import scala.language.higherKinds
import scala.{specialized => spec}

sealed abstract class ItemsAgentSortAlgorithm[Info[_]] {
protected type Agent[_] = ItemsAgent

type Setup[@spec(Grp) _]

def setupSort[@spec(Grp) Item: Info](items: Array[Item]): Setup[Item]

final def sortExplicit[@spec(Grp) Item](sortSetup: Setup[Item],
itemsAgent: ItemsAgent): Unit = {
implicit val setup: Setup[Item] = sortSetup
implicit val agent: Agent[_] = itemsAgent
sort()
}

protected def sort[@spec(Grp) Item: Setup, _: Agent](): Unit

protected final def a(implicit itemsAgent: Agent[_]): ItemsAgent =
itemsAgent

protected final def setup[@spec(Grp) Item: Setup]: Setup[Item] =
implicitly[Setup[Item]]

sealed trait Permit[+Item]

protected implicit def permit[Item]: Permit[Item] = thePermit

private val thePermit = new Permit[Nothing] {}
}

abstract class ComparableItemsAgentSortAlgorithm
extends ItemsAgentSortAlgorithm[Ordering]

abstract class NumericItemsAgentSortAlgorithm
extends ItemsAgentSortAlgorithm[Evidence]
Expand Up @@ -21,6 +21,6 @@ package pl.tarsa.sortalgobox.core.common

import scala.concurrent.duration.FiniteDuration

abstract class MeasuredSortAlgorithm[T] {
abstract class SelfMeasuredSortAlgorithm[T] {
def sort(array: Array[T]): FiniteDuration
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Piotr Tarsa ( http://github.com/tarsa )
* Copyright (C) 2015 - 2017 Piotr Tarsa ( http://github.com/tarsa )
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
Expand All @@ -16,15 +16,11 @@
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
*/
package pl.tarsa.sortalgobox.core.common

import pl.tarsa.sortalgobox.core.common.agents.ItemsAgent

import scala.language.higherKinds

abstract class PureSortAlgorithm[AgentType[ItemType] <: ItemsAgent[ItemType]] {
import scala.Specializable.Group

def sort[ItemType](itemsAgent: AgentType[ItemType]): Unit
object Specialization {
final val Group = new Group((Byte, Short, Int, Long))
}

0 comments on commit 34ff7f4

Please sign in to comment.