Skip to content

Commit ae067c3

Browse files
committed
Fixed the batchnorm backwards generation
1 parent 3c14e8f commit ae067c3

File tree

6 files changed

+58
-12
lines changed

6 files changed

+58
-12
lines changed

cmd/cudatest/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// cudatest tests the existence of CUDA by running a simple Go program that uses CUDA.
12
package main
23

34
import (
@@ -22,5 +23,4 @@ func main() {
2223
fmt.Printf("Memory :\t%v bytes\n", mem)
2324
fmt.Printf("Compute : \t%d.%d\n", maj, min)
2425
}
25-
2626
}

cmd/gencudnn/declarations.go

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ var ctypes2GoTypes = map[string]string{
5757

5858
var alphaBetaParams = []string{
5959
"alpha", "alpha1", "alpha2", "alpha3", "beta", "beta1",
60+
"alphaDataDiff", "alphaParamDiff", "betaDataDiff", "betaParamDiff",
6061
}
6162

6263
var builtins = map[string]string{

cmd/gencudnn/generatethis.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ func generateMappings(appendCurrent bool) {
4040
fmt.Fprintln(buf, initfn)
4141
bindgen.GenNameMap(buf, t, "fnNameMap", processNameBasic, functions, true)
4242
bindgen.GenNameMap(buf, t, "enumMappings", processNameBasic, enums, true)
43-
generateAlphaBeta(buf, t)
4443

4544
generateCRUD(buf, t, "create")
4645
generateCRUD(buf, t, "set")
4746
generateCRUD(buf, t, "destroy")
4847
generateCRUD(buf, t, "methods")
4948
fmt.Fprintln(buf, "}\n")
5049
}
50+
generateAlphaBeta(buf, t)
5151
fmt.Fprintln(buf, initfn)
5252
fmt.Fprintln(buf, "}\n")
5353
}

cmd/gencudnn/main.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func goimports(filename string) error {
5151
}
5252

5353
func main() {
54-
// pkg := parsePkg(false)
54+
pkg := parsePkg(false)
5555

5656
// Step 0: run parse.py to get more sanity about inputs and outputs
5757
// Step 1: Explore
@@ -66,19 +66,19 @@ func main() {
6666

6767
// Step 3: generate enums, then edit the file in the dnn package.
6868
// generateEnums()
69-
generateEnumStrings()
69+
// generateEnumStrings()
7070
// generateStubs(false, pkg) // true/false indicates debug mode
7171

7272
// Step 4: manual fix for inconsistent names (Spatial Transforms)
7373

7474
// step 5:
75-
// generateFunctions(pkg)
75+
generateFunctions(pkg)
7676

7777
// report things that aren't done yet
78-
// pkg = parsePkg(true)
79-
// reportPotentialNils(pkg)
80-
// reportUnconvertedFns(pkg, hdrfile, functions)
81-
// reportUnconvertedTypes(pkg, hdrfile, otherTypes, enums)
78+
pkg = parsePkg(true)
79+
reportPotentialNils(pkg)
80+
reportUnconvertedFns(pkg, hdrfile, functions)
81+
reportUnconvertedTypes(pkg, hdrfile, otherTypes, enums)
8282

8383
}
8484

cmd/gencudnn/mappings.go

+1
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ func init() {
360360
"cudnnDivisiveNormalizationBackward": {10: "beta", 3: "alpha"},
361361
"cudnnBatchNormalizationForwardTraining": {3: "beta", 2: "alpha"},
362362
"cudnnBatchNormalizationForwardInference": {3: "beta", 2: "alpha"},
363+
"cudnnBatchNormalizationBackward": {5: "betaParamDiff", 4: "alphaParamDiff", 3: "betaDataDiff", 2: "alphaDataDiff"},
363364
"cudnnSpatialTfSamplerForward": {6: "beta", 2: "alpha"},
364365
"cudnnSpatialTfSamplerBackward": {5: "beta", 2: "alpha"},
365366
}

dnn/generated_API.go

+47-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ func (dr *Dropout) RestoreDropoutDescriptor(handle *Context, dropout float32, st
1616
return result(C.cudnnRestoreDropoutDescriptor(dr.internal, handle.internal, C.float(dropout), states.Pointer(), C.size_t(stateSizeInBytes), C.ulonglong(seed)))
1717
}
1818

19+
// Derives a secondary tensor descriptor for BatchNormalization scale, invVariance, bnBias, bnScale subtensors from the layer's x data descriptor. Use the tensor descriptor produced by this function as the bnScaleBiasMeanVarDesc and bnScaleBiasDiffDesc parameters in Spatial and Per-Activation Batch Normalization forward and backward functions. Resulting dimensions will be 1xC(x1)x1x1 for BATCHNORM_MODE_SPATIAL and 1xC(xD)xHxW for BATCHNORM_MODE_PER_ACTIVATION (parentheses for 5D). For HALF input data type the resulting tensor descriptor will have a FLOAT type. For other data types it will have the same type as the input data.
20+
func (te *TensorDescriptor) DeriveBNTensorDescriptor(mode BatchNormMode) (derivedBnDesc *TensorDescriptor, err error) {
21+
// TODO: xDesc cudnnTensorDescriptor_t
22+
// call cudnnDeriveBNTensorDescriptor
23+
err = result(C.cudnnDeriveBNTensorDescriptor(te.internal, xDesc.internal, mode.C()))
24+
return
25+
}
26+
27+
// DropoutGetReserveSpaceSize is used to query the amount of reserve needed to run dropout with the input dimensions given by xDesc. The same reserve space is expected to be passed to cudnnDropoutForward and cudnnDropoutBackward, and its contents is expected to remain unchanged between cudnnDropoutForward and cudnnDropoutBackward calls.
28+
func (te *TensorDescriptor) DropoutGetReserveSpaceSize() (sizeInBytes uintptr, err error) {
29+
var sizeInBytesC C.size_t
30+
// call cudnnDropoutGetReserveSpaceSize
31+
err = result(C.cudnnDropoutGetReserveSpaceSize(te.internal, &sizeInBytesC))
32+
sizeInBytes = uintptr(sizeInBytesC)
33+
return
34+
}
35+
1936
// TransformTensor copies the scaled data from one tensor to another tensor with a different layout. Those descriptors need to have the same dimensions but not necessarily the same strides. The input and output tensors must not overlap in any way (i.e., tensors cannot be transformed in place). TransformTensor can be used to convert a tensor with an unsupported format to a supported one.
2037
func (co *Context) TransformTensor(alpha float64, xDesc *TensorDescriptor, x Memory, beta float64, yDesc *TensorDescriptor, y Memory) error {
2138
// DOUBLECHECK: "cudnnTransformTensor" returns Memory type in Parameter 6
@@ -534,8 +551,10 @@ func (co *Context) LRNCrossChannelBackward(normDesc *LRN, lrnMode LRNMode, alpha
534551
default:
535552
return errors.Errorf("Unsupported data type: %v", yDesc.dataType)
536553
}
554+
// TODO: dxDesc cudnnTensorDescriptor_t
537555
// call cudnnLRNCrossChannelBackward
538-
return result(C.cudnnLRNCrossChannelBackward(co.internal, normDesc.internal, lrnMode.C(), alphaC, yDesc.internal, y.Pointer(), dyDesc.internal, dy.Pointer(), xDesc.internal, x.Pointer(), betaC, dxDesc.internal, dx.Pointer()))
556+
err = result(C.cudnnLRNCrossChannelBackward(co.internal, normDesc.internal, lrnMode.C(), alphaC, yDesc.internal, y.Pointer(), dyDesc.internal, dy.Pointer(), xDesc.internal, x.Pointer(), betaC, dxDesc.internal, dx.Pointer()))
557+
return
539558
}
540559

541560
// DivisiveNormalizationForward performs the forward spatial DivisiveNormalization layer computation. It divides every value in a layer by the standard deviation of it's spatial neighbors as described in `What is the Best Multi-Stage Architecture for Object Recognition`, Jarrett 2009, Local Contrast Normalization Layer section. Note that Divisive Normalization only implements the x/max(c, sigma_x) portion of the computation, where sigma_x is the variance over the spatial neighborhood of x. The full LCN (Local Contrastive Normalization) computation can be implemented as a two-step process:
@@ -634,9 +653,34 @@ func (co *Context) BatchNormalizationForwardInference(mode BatchNormMode, alpha
634653
}
635654

636655
// BatchNormalizationBackward performs the backward BatchNormalization layer computation.
637-
func (co *Context) BatchNormalizationBackward(mode BatchNormMode, alphaDataDiff Memory, betaDataDiff Memory, alphaParamDiff Memory, betaParamDiff Memory, xDesc *TensorDescriptor, x Memory, dyDesc *TensorDescriptor, dy Memory, dxDesc *TensorDescriptor, dx Memory, dBnScaleBiasDesc *TensorDescriptor, bnScale Memory, dBnScaleResult Memory, dBnBiasResult Memory, epsilon float64, savedMean Memory, savedInvVariance Memory) error {
656+
func (co *Context) BatchNormalizationBackward(mode BatchNormMode, alphaDataDiff float64, betaDataDiff float64, alphaParamDiff float64, betaParamDiff float64, xDesc *TensorDescriptor, x Memory, dyDesc *TensorDescriptor, dy Memory, dxDesc *TensorDescriptor, dx Memory, dBnScaleBiasDesc *TensorDescriptor, bnScale Memory, dBnScaleResult Memory, dBnBiasResult Memory, epsilon float64, savedMean Memory, savedInvVariance Memory) error {
657+
var alphaDataDiffC, betaDataDiffC, alphaParamDiffC, betaParamDiffC unsafe.Pointer
658+
switch xDesc.dataType {
659+
case Float, Half:
660+
var alphaDataDiffF, betaDataDiffF, alphaParamDiffF, betaParamDiffF C.float
661+
alphaDataDiffF = C.float(float32(alphaDataDiff))
662+
betaDataDiffF = C.float(float32(betaDataDiff))
663+
alphaParamDiffF = C.float(float32(alphaParamDiff))
664+
betaParamDiffF = C.float(float32(betaParamDiff))
665+
alphaDataDiffC = unsafe.Pointer(&alphaDataDiffF)
666+
betaDataDiffC = unsafe.Pointer(&betaDataDiffF)
667+
alphaParamDiffC = unsafe.Pointer(&alphaParamDiffF)
668+
betaParamDiffC = unsafe.Pointer(&betaParamDiffF)
669+
case Double:
670+
var alphaDataDiffF, betaDataDiffF, alphaParamDiffF, betaParamDiffF C.double
671+
alphaDataDiffF = C.double(alphaDataDiff)
672+
betaDataDiffF = C.double(betaDataDiff)
673+
alphaParamDiffF = C.double(alphaParamDiff)
674+
betaParamDiffF = C.double(betaParamDiff)
675+
alphaDataDiffC = unsafe.Pointer(&alphaDataDiffF)
676+
betaDataDiffC = unsafe.Pointer(&betaDataDiffF)
677+
alphaParamDiffC = unsafe.Pointer(&alphaParamDiffF)
678+
betaParamDiffC = unsafe.Pointer(&betaParamDiffF)
679+
default:
680+
return errors.Errorf("Unsupported data type: %v", xDesc.dataType)
681+
}
638682
// call cudnnBatchNormalizationBackward
639-
return result(C.cudnnBatchNormalizationBackward(co.internal, mode.C(), alphaDataDiff.Pointer(), betaDataDiff.Pointer(), alphaParamDiff.Pointer(), betaParamDiff.Pointer(), xDesc.internal, x.Pointer(), dyDesc.internal, dy.Pointer(), dxDesc.internal, dx.Pointer(), dBnScaleBiasDesc.internal, bnScale.Pointer(), dBnScaleResult.Pointer(), dBnBiasResult.Pointer(), C.double(epsilon), savedMean.Pointer(), savedInvVariance.Pointer()))
683+
return result(C.cudnnBatchNormalizationBackward(co.internal, mode.C(), alphaDataDiffC, betaDataDiffC, alphaParamDiffC, betaParamDiffC, xDesc.internal, x.Pointer(), dyDesc.internal, dy.Pointer(), dxDesc.internal, dx.Pointer(), dBnScaleBiasDesc.internal, bnScale.Pointer(), dBnScaleResult.Pointer(), dBnBiasResult.Pointer(), C.double(epsilon), savedMean.Pointer(), savedInvVariance.Pointer()))
640684
}
641685

642686
// SpatialTfGridGeneratorForward generates a grid of coordinates in the input tensor corresponding to each pixel from the output tensor.

0 commit comments

Comments
 (0)