use of com.simiacryptus.mindseye.test.ToleranceStatistics 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.ToleranceStatistics in project MindsEye by SimiaCryptus.
the class CudaLayerTester method compareOutput.
/**
* Compare output tolerance statistics.
*
* @param expectedOutput the expected output
* @param actualOutput the actual output
* @return the tolerance statistics
*/
@Nonnull
public ToleranceStatistics compareOutput(final TensorList expectedOutput, final TensorList actualOutput) {
@Nonnull final ToleranceStatistics outputAgreement = IntStream.range(0, getBatchSize()).mapToObj(batch -> {
Tensor a = expectedOutput.get(batch);
Tensor b = actualOutput.get(batch);
ToleranceStatistics statistics = new ToleranceStatistics().accumulate(a.getData(), b.getData());
a.freeRef();
b.freeRef();
return statistics;
}).reduce((a, b) -> a.combine(b)).get();
if (!(outputAgreement.absoluteTol.getMax() < tolerance)) {
logger.info("Expected Output: " + expectedOutput.stream().map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
logger.info("Actual Output: " + actualOutput.stream().map(x -> {
String str = x.prettyPrint();
x.freeRef();
return str;
}).collect(Collectors.toList()));
throw new AssertionError("Output Corrupt: " + outputAgreement);
}
return outputAgreement;
}
use of com.simiacryptus.mindseye.test.ToleranceStatistics 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.ToleranceStatistics in project MindsEye by SimiaCryptus.
the class CudaLayerTester method test.
/**
* Test tolerance statistics.
*
* @param log
* @param layer the reference
* @param inputPrototype the input prototype
* @return the tolerance statistics
*/
@Override
public ToleranceStatistics test(@Nonnull final NotebookOutput log, final Layer layer, @Nonnull final Tensor... inputPrototype) {
log.h1("GPU/Cuda Behavior");
layer.setFrozen(false);
if (null == layer)
return new ToleranceStatistics();
ToleranceStatistics statistics = testInterGpu(log, layer, inputPrototype);
try {
statistics = statistics.combine(testNonstandardBounds(log, layer, inputPrototype));
statistics = statistics.combine(testNonstandardBoundsBackprop(log, layer, inputPrototype));
} catch (Throwable e) {
logger.warn("Error testing support for tensor views", e);
throw e;
}
return statistics;
}
use of com.simiacryptus.mindseye.test.ToleranceStatistics 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;
}
Aggregations