diff --git a/Caller/build.sbt b/Caller/build.sbt new file mode 100644 index 00000000..b6e5faf0 --- /dev/null +++ b/Caller/build.sbt @@ -0,0 +1,2 @@ +libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value +libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % Test diff --git a/Caller/src/main/scala/com/thoughtworks/deeplearning/Caller.scala b/Caller/src/main/scala/com/thoughtworks/deeplearning/Caller.scala new file mode 100644 index 00000000..96999508 --- /dev/null +++ b/Caller/src/main/scala/com/thoughtworks/deeplearning/Caller.scala @@ -0,0 +1,14 @@ +package com.thoughtworks.deeplearning + +import scala.language.experimental.macros +import scala.reflect.macros.whitebox + +final case class Caller[A](value: A) +object Caller { + implicit def generate: Caller[_] = macro impl + + def impl(c: whitebox.Context): c.Tree = { + import c.universe._ + q"new _root_.com.thoughtworks.deeplearning.Caller(this)" + } +} diff --git a/Caller/src/test/scala/com/thoughtworks/deeplearning/CallerSpec.scala b/Caller/src/test/scala/com/thoughtworks/deeplearning/CallerSpec.scala new file mode 100644 index 00000000..0abe0809 --- /dev/null +++ b/Caller/src/test/scala/com/thoughtworks/deeplearning/CallerSpec.scala @@ -0,0 +1,17 @@ +package com.thoughtworks.deeplearning + +import org.scalatest.{FreeSpec, Matchers} + +object Foo { + def call(implicit caller: Caller[_]): String = { + caller.value.getClass.getName + } +} + +class CallerSpec extends FreeSpec with Matchers { + "className" in { + val className: String = Foo.call + className should be(this.getClass.getName) + } + +} diff --git a/LogRecords/src/main/scala/com/thoughtworks/deeplearning/LogRecords.scala b/LogRecords/src/main/scala/com/thoughtworks/deeplearning/LogRecords.scala index 065f68c3..923ed3a6 100644 --- a/LogRecords/src/main/scala/com/thoughtworks/deeplearning/LogRecords.scala +++ b/LogRecords/src/main/scala/com/thoughtworks/deeplearning/LogRecords.scala @@ -10,11 +10,11 @@ object LogRecords { private[LogRecords] abstract class LazyLogRecord(level: Level, customMessage: String = null)( implicit fullName: sourcecode.FullName, methodName: sourcecode.Name, - fileName: sourcecode.File) + className: Caller[_]) extends LogRecord(level, customMessage) { setLoggerName(fullName.value) - setSourceClassName(fileName.value) + setSourceClassName(className.value.getClass.getName) setSourceMethodName(methodName.value) protected def makeDefaultMessage: Fastring @@ -28,18 +28,27 @@ object LogRecords { } - final case class UncaughtExceptionDuringBackward(thrown: Throwable, customMessage: String = null) - extends LazyLogRecord(Level.SEVERE, customMessage) { + final case class UncaughtExceptionDuringBackward( + thrown: Throwable)(implicit fullName: sourcecode.FullName, methodName: sourcecode.Name, className: Caller[_]) + extends LazyLogRecord(Level.SEVERE) { setThrown(thrown) override protected def makeDefaultMessage = fast"An exception raised during backward" } - final case class DeltaAccumulatorTracker(customMessage: String) extends LazyLogRecord(Level.FINER, customMessage) { - override protected def makeDefaultMessage: Fastring = fast"DeltaAccumulatorTracker default message" + final case class DeltaAccumulatorIsUpdating[Delta]( + deltaAccumulator: Delta, + delta: Delta)(implicit fullName: sourcecode.FullName, methodName: sourcecode.Name, className: Caller[_]) + extends LazyLogRecord(Level.FINER) { + override protected def makeDefaultMessage: Fastring = + fast"Before deltaAccumulator update, deltaAccumulator is : $deltaAccumulator, delta is : $delta" } - final case class FloatWeightTracker(customMessage: String) extends LazyLogRecord(Level.FINER, customMessage) { - override protected def makeDefaultMessage: Fastring = fast"FloatWeightTracker default message" + final case class WeightIsUpdating[Delta](data: Delta, delta: Delta)(implicit fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]) + extends LazyLogRecord(Level.FINER) { + override protected def makeDefaultMessage: Fastring = + fast"Before weight update, weight is : $data, delta is : $delta" } } diff --git a/TapeTaskFactory/src/main/scala/com/thoughtworks/deeplearning/TapeTaskFactory.scala b/TapeTaskFactory/src/main/scala/com/thoughtworks/deeplearning/TapeTaskFactory.scala index fc5c3cc9..5e966976 100644 --- a/TapeTaskFactory/src/main/scala/com/thoughtworks/deeplearning/TapeTaskFactory.scala +++ b/TapeTaskFactory/src/main/scala/com/thoughtworks/deeplearning/TapeTaskFactory.scala @@ -2,7 +2,7 @@ package com.thoughtworks.deeplearning import java.util.logging.{Level, Logger} -import com.thoughtworks.deeplearning.LogRecords.{DeltaAccumulatorTracker, UncaughtExceptionDuringBackward} +import com.thoughtworks.deeplearning.LogRecords.{DeltaAccumulatorIsUpdating, UncaughtExceptionDuringBackward} import com.thoughtworks.deeplearning.Tape.Aux import com.thoughtworks.raii._ @@ -31,7 +31,10 @@ object TapeTaskFactory { operand1: Do[_ <: Tape.Aux[Data1, Delta1]])( computeForward: (Data0, Data1) => Task[(OutputData, OutputDelta => (Do[_ <: Delta0], Do[_ <: Delta1]))])( implicit binaryTapeTaskFactory: BinaryTapeTaskFactory[OutputData, OutputDelta], - logger: Logger): Do[Tape.Aux[OutputData, OutputDelta]] = { + logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): Do[Tape.Aux[OutputData, OutputDelta]] = { binaryTapeTaskFactory(operand0, operand1)(computeForward) } @@ -39,12 +42,18 @@ object TapeTaskFactory { def unary[Data, Delta, OutputData, OutputDelta](operand: Do[_ <: Tape.Aux[Data, Delta]])( computeForward: (Data) => Task[(OutputData, OutputDelta => Do[_ <: Delta])])( implicit unaryTapeTaskFactory: UnaryTapeTaskFactory[OutputData, OutputDelta], - logger: Logger): Do[Tape.Aux[OutputData, OutputDelta]] = { + logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): Do[Tape.Aux[OutputData, OutputDelta]] = { unaryTapeTaskFactory(operand)(computeForward) } private abstract class Output[OutputData, OutputDelta: Monoid](override val data: OutputData)( - implicit logger: Logger) + implicit logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]) extends Tape with ResourceT[Future, Try[Tape.Aux[OutputData, OutputDelta]]] { @@ -67,7 +76,7 @@ object TapeTaskFactory { tryDelta.map { delta => synchronized { if (logger.isLoggable(Level.FINER)) { - logger.log(DeltaAccumulatorTracker(s"deltaAccumulator:$deltaAccumulator, delta: $delta")) + logger.log(DeltaAccumulatorIsUpdating(deltaAccumulator, delta)) } deltaAccumulator |+|= delta } @@ -76,7 +85,7 @@ object TapeTaskFactory { ResourceFactoryT.run(tryTRAIIFuture).flatMap { case Failure(e) => - logger.log(UncaughtExceptionDuringBackward(e, "An exception raised during backward")) + logger.log(UncaughtExceptionDuringBackward(e)) Future.now(()) case Success(()) => Future.now(()) @@ -126,7 +135,10 @@ object TapeTaskFactory { } } - final class MonoidBinaryTapeTaskFactory[OutputData, OutputDelta: Monoid](implicit logger: Logger) + final class MonoidBinaryTapeTaskFactory[OutputData, OutputDelta: Monoid](implicit logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]) extends BinaryTapeTaskFactory[OutputData, OutputDelta] { @inline override def apply[Data0, Delta0, Data1, Delta1](operand0: Do[_ <: Tape.Aux[Data0, Delta0]], @@ -182,13 +194,19 @@ object TapeTaskFactory { @inline implicit def monoidBinaryTapeTaskFactory[OutputData, OutputDelta: Monoid]( - implicit logger: Logger): BinaryTapeTaskFactory[OutputData, OutputDelta] = { + implicit logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): BinaryTapeTaskFactory[OutputData, OutputDelta] = { new MonoidBinaryTapeTaskFactory[OutputData, OutputDelta] } } object UnaryTapeTaskFactory { - final class MonoidUnaryTapeTaskFactory[OutputData, OutputDelta: Monoid](implicit logger: Logger) + final class MonoidUnaryTapeTaskFactory[OutputData, OutputDelta: Monoid](implicit logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]) extends UnaryTapeTaskFactory[OutputData, OutputDelta] { @inline override def apply[Data, Delta](operand: Do[_ <: Tape.Aux[Data, Delta]])( @@ -224,7 +242,10 @@ object TapeTaskFactory { @inline implicit def monoidUnaryTapeTaskFactory[OutputData, OutputDelta: Monoid]( - implicit logger: Logger): UnaryTapeTaskFactory[OutputData, OutputDelta] = { + implicit logger: Logger, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): UnaryTapeTaskFactory[OutputData, OutputDelta] = { new MonoidUnaryTapeTaskFactory[OutputData, OutputDelta] } } diff --git a/build.sbt b/build.sbt index 28c7d12c..2b40049e 100644 --- a/build.sbt +++ b/build.sbt @@ -20,19 +20,21 @@ lazy val Memory = project lazy val Tape = project.dependsOn(ProjectRef(file("RAII.scala"), "packageJVM"), LogRecords, ProjectRef(file("RAII.scala"), "Do")) -lazy val TapeTaskFactory = project.dependsOn(Tape, ProjectRef(file("RAII.scala"), "Do")) +lazy val TapeTaskFactory = project.dependsOn(Tape, ProjectRef(file("RAII.scala"), "Do"), Caller) lazy val Closeables = project +lazy val Caller = project + includeFilter in unmanagedSources := (includeFilter in unmanagedSources).value && new SimpleFileFilter(_.isFile) lazy val OpenCL = project.dependsOn(Closeables, Memory, ProjectRef(file("RAII.scala"), "ResourceFactoryTJVM")) //lazy val LayerFactory = project.dependsOn(DifferentiableKernel) -lazy val `differentiable-float` = project.dependsOn(TapeTask, TapeTaskFactory, PolyFunctions) +lazy val `differentiable-float` = project.dependsOn(TapeTask, TapeTaskFactory, PolyFunctions, Caller) -lazy val `differentiable-double` = project.dependsOn(TapeTask, TapeTaskFactory, PolyFunctions) +lazy val `differentiable-double` = project.dependsOn(TapeTask, TapeTaskFactory, PolyFunctions, Caller) val FloatRegex = """(?i:float)""".r @@ -62,7 +64,7 @@ lazy val PolyFunctions = project.dependsOn(ToTapeTask) lazy val TapeTask = project.dependsOn(Tape, ProjectRef(file("RAII.scala"), "Do")) -lazy val LogRecords = project +lazy val LogRecords = project.dependsOn(Caller) lazy val AsynchronousSemaphore = project diff --git a/differentiable-float/src/main/scala/com/thoughtworks/deeplearning/differentiable/float.scala b/differentiable-float/src/main/scala/com/thoughtworks/deeplearning/differentiable/float.scala index 96c9e046..bdf2e1a5 100644 --- a/differentiable-float/src/main/scala/com/thoughtworks/deeplearning/differentiable/float.scala +++ b/differentiable-float/src/main/scala/com/thoughtworks/deeplearning/differentiable/float.scala @@ -3,7 +3,7 @@ package differentiable import java.util.logging.{Level, Logger} -import com.thoughtworks.deeplearning.LogRecords.{FloatWeightTracker, UncaughtExceptionDuringBackward} +import com.thoughtworks.deeplearning.LogRecords.{WeightIsUpdating, UncaughtExceptionDuringBackward} import com.thoughtworks.deeplearning.PolyFunctions._ import com.thoughtworks.deeplearning.TapeTask.Trainable import com.thoughtworks.raii.future.Do @@ -60,7 +60,10 @@ object float { } final case class Weight(var data: Float)(implicit optimizerFactory: OptimizerFactory, - logger: Logger = Logger.getGlobal) + logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) extends Tape { private val optimizer: Optimizer = optimizerFactory.floatOptimizer(this) @@ -78,7 +81,7 @@ object float { tryDelta.map { delta => synchronized { if (logger.isLoggable(Level.FINER)) { - logger.log(FloatWeightTracker(s"weight: $data, delta:$delta")) + logger.log(WeightIsUpdating(data, delta)) } data = optimizer.updateFloat(data, delta) } @@ -87,7 +90,7 @@ object float { ResourceFactoryT.run(tryTRAIIFuture).flatMap { case Failure(e) => - logger.log(UncaughtExceptionDuringBackward(e, "An exception raised during backward")) + logger.log(UncaughtExceptionDuringBackward(e)) Future.now(()) case Success(()) => Future.now(()) @@ -117,7 +120,11 @@ object float { implicit def liftFloat[A](implicit typeClass: ToTapeTask.Aux[A, Float, Float]): ToTapeTask.Aux[A, Float, Float] = typeClass implicit final class FloatToWeightOps(value: Float) { - def toWeight(implicit optimizerFactory: OptimizerFactory, logger: Logger = Logger.getGlobal): Weight = { + def toWeight(implicit optimizerFactory: OptimizerFactory, + logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name): Weight = { Weight(value) } } @@ -127,7 +134,10 @@ object float { } @inline - implicit def `Float+Float`(implicit logger: Logger = Logger.getGlobal) + implicit def `Float+Float`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyMethods.+.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyMethods.+.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -145,7 +155,10 @@ object float { } @inline - implicit def `Float-Float`(implicit logger: Logger = Logger.getGlobal) + implicit def `Float-Float`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyMethods.-.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyMethods.-.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -163,7 +176,10 @@ object float { } @inline - implicit def `Float*Float`(implicit logger: Logger = Logger.getGlobal) + implicit def `Float*Float`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyMethods.*.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyMethods.*.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -181,7 +197,10 @@ object float { } @inline - implicit def `Float/Float`(implicit logger: Logger = Logger.getGlobal) + implicit def `Float/Float`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyMethods./.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyMethods./.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -199,7 +218,10 @@ object float { } @inline - implicit def `min(Float,Float)`(implicit logger: Logger = Logger.getGlobal) + implicit def `min(Float,Float)`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyFunctions.min.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyFunctions.min.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -218,7 +240,10 @@ object float { } @inline - implicit def `max(Float,Float)`(implicit logger: Logger = Logger.getGlobal) + implicit def `max(Float,Float)`(implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name) : PolyFunctions.max.Case.Aux[Do.Covariant[FloatTape], Do.Covariant[FloatTape], Do[FloatTape]] = { PolyFunctions.max.at { (operand0, operand1) => TapeTaskFactory.binary(operand0, operand1) { (data0, data1) => @@ -237,8 +262,11 @@ object float { } @inline - implicit def `log(Float)`(implicit logger: Logger = Logger.getGlobal) - : PolyFunctions.log.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { + implicit def `log(Float)`( + implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + className: Caller[_], + methodName: sourcecode.Name): PolyFunctions.log.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { PolyFunctions.log.at { operand => TapeTaskFactory.unary(operand) { data => Task.delay { @@ -253,8 +281,11 @@ object float { } @inline - implicit def `exp(Float)`(implicit logger: Logger = Logger.getGlobal) - : PolyFunctions.exp.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { + implicit def `exp(Float)`( + implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): PolyFunctions.exp.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { PolyFunctions.exp.at { operand => TapeTaskFactory.unary(operand) { data => Task.delay { @@ -269,8 +300,11 @@ object float { } @inline - implicit def `abs(Float)`(implicit logger: Logger = Logger.getGlobal) - : PolyFunctions.abs.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { + implicit def `abs(Float)`( + implicit logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]): PolyFunctions.abs.Case.Aux[Do.Covariant[FloatTape], Do[FloatTape]] = { PolyFunctions.abs.at { operand => TapeTaskFactory.unary(operand) { data => Task.delay { @@ -286,7 +320,10 @@ object float { } implicit final class DifferentiableFloatOps[From](from: From)(implicit lift: ToTapeTask.Aux[From, Float, Float], - logger: Logger = Logger.getGlobal) { + logger: Logger = Logger.getGlobal, + fullName: sourcecode.FullName, + methodName: sourcecode.Name, + className: Caller[_]) { private val operand: Do.Covariant[FloatTape] = lift(from) @inline def unary_- : Do[FloatTape] = {