// Set the simulation mesh to Nx x Ny x Nz cells of given size. // Can be set only once at the beginning of the simulation. // TODO: dedup arguments from globals func SetMesh(Nx, Ny, Nz int, cellSizeX, cellSizeY, cellSizeZ float64, pbcx, pbcy, pbcz int) { SetBusy(true) defer SetBusy(false) arg("GridSize", Nx > 0 && Ny > 0 && Nz > 0) arg("CellSize", cellSizeX > 0 && cellSizeY > 0 && cellSizeZ > 0) arg("PBC", pbcx >= 0 && pbcy >= 0 && pbcz >= 0) prevSize := globalmesh_.Size() pbc := []int{pbcx, pbcy, pbcz} if globalmesh_.Size() == [3]int{0, 0, 0} { // first time mesh is set globalmesh_ = *data.NewMesh(Nx, Ny, Nz, cellSizeX, cellSizeY, cellSizeZ, pbc...) M.alloc() regions.alloc() } else { // here be dragons LogOut("resizing...") // free everything conv_.Free() conv_ = nil mfmconv_.Free() mfmconv_ = nil cuda.FreeBuffers() // resize everything globalmesh_ = *data.NewMesh(Nx, Ny, Nz, cellSizeX, cellSizeY, cellSizeZ, pbc...) M.resize() regions.resize() geometry.buffer.Free() geometry.buffer = data.NilSlice(1, Mesh().Size()) geometry.setGeom(geometry.shape) // remove excitation extra terms if they don't fit anymore // up to the user to add them again if Mesh().Size() != prevSize { B_ext.RemoveExtraTerms() J.RemoveExtraTerms() } if Mesh().Size() != prevSize { B_therm.noise.Free() B_therm.noise = nil } } lazy_gridsize = []int{Nx, Ny, Nz} lazy_cellsize = []float64{cellSizeX, cellSizeY, cellSizeZ} lazy_pbc = []int{pbcx, pbcy, pbcz} }
// Compares FFT-accelerated convolution against brute-force on sparse data. // This is not really needed but very quickly uncovers newly introduced bugs. func testConvolution(c *DemagConvolution, PBC [3]int, realKern [3][3]*data.Slice) { if PBC != [3]int{0, 0, 0} || prod(c.inputSize) > 512*512 { // the brute-force method does not work for pbc, // and for large simulations it gets just too slow. util.Log("skipping convolution self-test") return } //fmt.Print("convolution test ") inhost := data.NewSlice(3, c.inputSize) initConvTestInput(inhost.Vectors()) gpu := NewSlice(3, c.inputSize) defer gpu.Free() data.Copy(gpu, inhost) regions := NewBytes(prod(c.inputSize)) defer regions.Free() Bsat := NewSlice(1, [3]int{1, 1, 256}) defer Bsat.Free() Memset(Bsat, 1) BsatLUT := LUTPtr(Bsat.DevPtr(0)) vol := data.NilSlice(1, c.inputSize) c.Exec(gpu, gpu, vol, BsatLUT, regions) output := gpu.HostCopy() brute := data.NewSlice(3, c.inputSize) bruteConv(inhost.Vectors(), brute.Vectors(), realKern) a, b := output.Host(), brute.Host() err := float32(0) for c := range a { for i := range a[c] { if fabs(a[c][i]-b[c][i]) > err { err = fabs(a[c][i] - b[c][i]) } } } if err > CONV_TOLERANCE { util.Fatal("convolution self-test tolerance: ", err, " FAIL") } }
// Compares FFT-accelerated convolution against brute-force on sparse data. // This is not really needed but very quickly uncovers newly introduced bugs. func testConvolution(c *DemagConvolution, PBC [3]int, realKern [3][3]*data.Slice) { if PBC != [3]int{0, 0, 0} { // the brute-force method does not work for pbc. util.Log("skipping convolution self-test for PBC") return } util.Log("//convolution self-test...") inhost := data.NewSlice(3, c.inputSize) initConvTestInput(inhost.Vectors()) gpu := NewSlice(3, c.inputSize) defer gpu.Free() data.Copy(gpu, inhost) Msat := NewSlice(1, [3]int{1, 1, 256}) defer Msat.Free() Memset(Msat, 1) vol := data.NilSlice(1, c.inputSize) c.Exec(gpu, gpu, vol, ToMSlice(Msat)) output := gpu.HostCopy() brute := data.NewSlice(3, c.inputSize) bruteConv(inhost.Vectors(), brute.Vectors(), realKern) a, b := output.Host(), brute.Host() err := float32(0) for c := range a { for i := range a[c] { if fabs(a[c][i]-b[c][i]) > err { err = fabs(a[c][i] - b[c][i]) } } } if err > CONV_TOLERANCE { util.Fatal("convolution self-test tolerance: ", err, " FAIL") } }
func (g *geom) Gpu() *data.Slice { if g.buffer == nil { g.buffer = data.NilSlice(1, g.Mesh().Size()) } return g.buffer }