use of com.simiacryptus.mindseye.test.SimpleResult in project MindsEye by SimiaCryptus.
the class BatchingTester method test.
/**
* Test tolerance statistics.
*
* @param reference the reference
* @param inputPrototype the input prototype
* @return the tolerance statistics
*/
@Nonnull
public ToleranceStatistics test(@Nullable final Layer reference, @Nonnull final Tensor[] inputPrototype) {
if (null == reference)
return new ToleranceStatistics();
final TensorList[] inputTensorLists = Arrays.stream(inputPrototype).map(t -> TensorArray.wrap(IntStream.range(0, getBatchSize()).mapToObj(i -> t.map(v -> getRandom())).toArray(i -> new Tensor[i]))).toArray(i -> new TensorList[i]);
@Nonnull final SimpleResult asABatch;
final List<SimpleEval> oneAtATime;
try {
asABatch = SimpleListEval.run(reference, inputTensorLists);
oneAtATime = IntStream.range(0, getBatchSize()).mapToObj(batch -> {
Tensor[] inputTensors = IntStream.range(0, inputTensorLists.length).mapToObj(i -> inputTensorLists[i].get(batch)).toArray(i -> new Tensor[i]);
@Nonnull SimpleEval eval = SimpleEval.run(reference, inputTensors);
for (@Nonnull Tensor tensor : inputTensors) {
tensor.freeRef();
}
return eval;
}).collect(Collectors.toList());
} finally {
for (@Nonnull TensorList tensorList : inputTensorLists) {
tensorList.freeRef();
}
}
try {
TensorList batchOutput = asABatch.getOutput();
@Nonnull IntFunction<ToleranceStatistics> toleranceStatisticsIntFunction = batch -> {
@Nullable Tensor batchTensor = batchOutput.get(batch);
@Nonnull ToleranceStatistics accumulate = new ToleranceStatistics().accumulate(batchTensor.getData(), oneAtATime.get(batch).getOutput().getData());
batchTensor.freeRef();
return accumulate;
};
int batchLength = batchOutput.length();
@Nonnull final ToleranceStatistics outputAgreement = IntStream.range(0, Math.min(getBatchSize(), batchLength)).mapToObj(toleranceStatisticsIntFunction).reduce((a, b) -> a.combine(b)).get();
if (!(outputAgreement.absoluteTol.getMax() < tolerance)) {
logger.info("Batch Output: " + batchOutput.stream().map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
logger.info("Singular Output: " + oneAtATime.stream().map(x -> x.getOutput().prettyPrint()).collect(Collectors.toList()));
throw new AssertionError("Output Corrupt: " + outputAgreement);
}
ToleranceStatistics derivativeAgreement = IntStream.range(0, Math.min(getBatchSize(), batchLength)).mapToObj(batch -> {
IntFunction<ToleranceStatistics> statisticsFunction = input -> {
@Nullable Tensor a = asABatch.getInputDerivative()[input].get(batch);
Tensor b = oneAtATime.get(batch).getDerivative()[input];
@Nonnull Tensor diff = a.minus(b);
logger.info("Error: " + diff.prettyPrint());
logger.info("Scalar Statistics: " + new ScalarStatistics().add(diff.getData()).getMetrics());
double[][] points = Arrays.stream(diff.getData()).mapToObj(x -> new double[] { x }).toArray(i -> new double[i][]);
// logger.info("Density: " + new DensityTree("x").setMinSplitFract(1e-8).setSplitSizeThreshold(2).new Node(points));
diff.freeRef();
@Nonnull ToleranceStatistics toleranceStatistics = new ToleranceStatistics().accumulate(a.getData(), b.getData());
a.freeRef();
return toleranceStatistics;
};
return IntStream.range(0, Math.min(inputPrototype.length, batchLength)).mapToObj(statisticsFunction).reduce((a, b) -> a.combine(b)).orElse(null);
}).filter(x -> x != null).reduce((a, b) -> a.combine(b)).orElse(null);
if (null != derivativeAgreement && !(derivativeAgreement.absoluteTol.getMax() < tolerance)) {
throw new AssertionError("Derivatives Corrupt: " + derivativeAgreement);
}
return null != derivativeAgreement ? derivativeAgreement.combine(outputAgreement) : outputAgreement;
} finally {
asABatch.freeRef();
oneAtATime.forEach(x -> x.freeRef());
}
}
use of com.simiacryptus.mindseye.test.SimpleResult in project MindsEye by SimiaCryptus.
the class CudaLayerTester method testNonstandardBoundsBackprop.
/**
* Test nonstandard bounds backprop tolerance statistics.
*
* @param log the log
* @param layer the layer
* @param inputPrototype the input prototype
* @return the tolerance statistics
*/
@Nonnull
public ToleranceStatistics testNonstandardBoundsBackprop(final NotebookOutput log, @Nullable final Layer layer, @Nonnull final Tensor[] inputPrototype) {
log.h2("Irregular Backprop");
log.p("This layer should accept non-dense tensors as delta input.");
return log.code(() -> {
Tensor[] randomized = Arrays.stream(inputPrototype).map(x -> x.map(v -> getRandom())).toArray(i -> new Tensor[i]);
logger.info("Input: " + Arrays.stream(randomized).map(Tensor::prettyPrint).collect(Collectors.toList()));
Precision precision = Precision.Double;
TensorList[] controlInput = Arrays.stream(randomized).map(original -> {
return TensorArray.wrap(original);
}).toArray(i -> new TensorList[i]);
@Nonnull final SimpleResult testResult = CudaSystem.run(gpu -> {
TensorList[] copy = copy(controlInput);
SimpleResult result = new SimpleGpuEval(layer, gpu, copy) {
@Nonnull
@Override
public TensorList getFeedback(@Nonnull final TensorList original) {
Tensor originalTensor = original.get(0).mapAndFree(x -> 1);
CudaTensorList cudaTensorList = buildIrregularCudaTensor(gpu, precision, originalTensor);
originalTensor.freeRef();
return cudaTensorList;
}
}.call();
Arrays.stream(copy).forEach(ReferenceCounting::freeRef);
return result;
});
@Nonnull final SimpleResult controlResult = CudaSystem.run(gpu -> {
TensorList[] copy = copy(controlInput);
SimpleResult result = SimpleGpuEval.run(layer, gpu, copy);
Arrays.stream(copy).forEach(ReferenceCounting::freeRef);
return result;
}, 1);
try {
ToleranceStatistics compareOutput = compareOutput(controlResult, testResult);
ToleranceStatistics compareDerivatives = compareDerivatives(controlResult, testResult);
return compareDerivatives.combine(compareOutput);
} finally {
Arrays.stream(controlInput).forEach(ReferenceCounting::freeRef);
controlResult.freeRef();
testResult.freeRef();
}
});
}
use of com.simiacryptus.mindseye.test.SimpleResult in project MindsEye by SimiaCryptus.
the class CudaLayerTester method testInterGpu.
/**
* Test inter gpu tolerance statistics.
*
* @param log the log
* @param reference the reference
* @param inputPrototype the input prototype
* @return the tolerance statistics
*/
@Nonnull
public ToleranceStatistics testInterGpu(final NotebookOutput log, @Nullable final Layer reference, @Nonnull final Tensor[] inputPrototype) {
log.h2("Multi-GPU Compatibility");
log.p("This layer should be able to apply using a GPU context other than the one used to create the inputs.");
return log.code(() -> {
final TensorList[] heapInput = Arrays.stream(inputPrototype).map(t -> TensorArray.wrap(IntStream.range(0, getBatchSize()).mapToObj(i -> t.map(v -> getRandom())).toArray(i -> new Tensor[i]))).toArray(i -> new TensorList[i]);
logger.info("Input: " + Arrays.stream(heapInput).flatMap(x -> x.stream()).map(tensor -> {
String prettyPrint = tensor.prettyPrint();
tensor.freeRef();
return prettyPrint;
}).collect(Collectors.toList()));
TensorList[] gpuInput = CudaSystem.run(gpu -> {
return Arrays.stream(heapInput).map(original -> {
return CudaTensorList.wrap(gpu.getTensor(original, Precision.Double, MemoryType.Managed, false), original.length(), original.getDimensions(), Precision.Double);
}).toArray(i -> new TensorList[i]);
}, 0);
@Nonnull final SimpleResult fromHeap = CudaSystem.run(gpu -> {
return SimpleGpuEval.run(reference, gpu, heapInput);
}, 1);
@Nonnull final SimpleResult fromGPU = CudaSystem.run(gpu -> {
return SimpleGpuEval.run(reference, gpu, gpuInput);
}, 1);
try {
ToleranceStatistics compareOutput = compareOutput(fromHeap, fromGPU);
ToleranceStatistics compareDerivatives = compareDerivatives(fromHeap, fromGPU);
return compareDerivatives.combine(compareOutput);
} finally {
Arrays.stream(gpuInput).forEach(ReferenceCounting::freeRef);
Arrays.stream(heapInput).forEach(x -> x.freeRef());
fromGPU.freeRef();
fromHeap.freeRef();
}
});
}
use of com.simiacryptus.mindseye.test.SimpleResult in project MindsEye by SimiaCryptus.
the class CudaLayerTester method compareInputDerivatives.
/**
* Compare input derivatives tolerance statistics.
*
* @param expected the expected
* @param actual the actual
* @return the tolerance statistics
*/
@Nonnull
public ToleranceStatistics compareInputDerivatives(final SimpleResult expected, final SimpleResult actual) {
@Nonnull final ToleranceStatistics derivativeAgreement = IntStream.range(0, getBatchSize()).mapToObj(batch -> {
@Nonnull IntFunction<ToleranceStatistics> compareInputDerivative = input -> {
Tensor b = actual.getInputDerivative()[input].get(batch);
Tensor a = expected.getInputDerivative()[input].get(batch);
ToleranceStatistics statistics = new ToleranceStatistics().accumulate(a.getData(), b.getData());
a.freeRef();
b.freeRef();
return statistics;
};
return IntStream.range(0, expected.getOutput().length()).mapToObj(compareInputDerivative).reduce((a, b) -> a.combine(b)).get();
}).reduce((a, b) -> a.combine(b)).get();
if (!(derivativeAgreement.absoluteTol.getMax() < tolerance)) {
logger.info("Expected Derivative: " + Arrays.stream(expected.getInputDerivative()).flatMap(TensorList::stream).map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
logger.info("Actual Derivative: " + Arrays.stream(actual.getInputDerivative()).flatMap(TensorList::stream).map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
throw new AssertionError("Input Derivatives Corrupt: " + derivativeAgreement);
}
return derivativeAgreement;
}
use of com.simiacryptus.mindseye.test.SimpleResult in project MindsEye by SimiaCryptus.
the class CudaLayerTester method compareLayerDerivatives.
/**
* Compare layer derivatives tolerance statistics.
*
* @param expected the expected
* @param actual the actual
* @return the tolerance statistics
*/
@Nullable
public ToleranceStatistics compareLayerDerivatives(final SimpleResult expected, final SimpleResult actual) {
@Nonnull final ToleranceStatistics derivativeAgreement = IntStream.range(0, getBatchSize()).mapToObj(batch -> {
@Nonnull Function<Layer, ToleranceStatistics> compareInputDerivative = input -> {
double[] b = actual.getLayerDerivative().getMap().get(input).getDelta();
double[] a = expected.getLayerDerivative().getMap().get(input).getDelta();
ToleranceStatistics statistics = new ToleranceStatistics().accumulate(a, b);
return statistics;
};
return Stream.concat(actual.getLayerDerivative().getMap().keySet().stream(), expected.getLayerDerivative().getMap().keySet().stream()).distinct().map(compareInputDerivative).reduce((a, b) -> a.combine(b));
}).filter(x -> x.isPresent()).map(x -> x.get()).reduce((a, b) -> a.combine(b)).orElse(null);
if (null != derivativeAgreement && !(derivativeAgreement.absoluteTol.getMax() < tolerance)) {
logger.info("Expected Derivative: " + Arrays.stream(expected.getInputDerivative()).flatMap(TensorList::stream).map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
logger.info("Actual Derivative: " + Arrays.stream(actual.getInputDerivative()).flatMap(TensorList::stream).map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
throw new AssertionError("Layer Derivatives Corrupt: " + derivativeAgreement);
}
return derivativeAgreement;
}
Aggregations