def sparse_GD(T, U, V, W, Lambda, omega, I, J, K, r, stepSize): iteration_count = 0 E = ctf.tensor((I, J, K)) E.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda norm = [curr_err_norm] while True: U = sparse_updateU(T, U, V, W, Lambda, omega, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") V = sparse_updateV(T, U, V, W, Lambda, omega, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") W = sparse_updateW(T, U, V, W, Lambda, omega, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda if abs(curr_err_norm - next_err_norm) < .01 or iteration_count > 100: break print(curr_err_norm, next_err_norm, ctf.vecnorm(E)) curr_err_norm = next_err_norm if iteration_count % 5 == 0: norm.append(curr_err_norm) iteration_count += 1 print("Number of iterations: ", iteration_count) return norm
def get_objective(T, U, V, W, I, J, K, omega, regParam): L = ctf.tensor((I, J, K)) t0 = time.time() L.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") t1 = time.time() objective = ctf.vecnorm(L) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam t2 = time.time() if glob_comm.rank() == 0: print('generate L takes {}'.format(t1 - t0)) print('calc objective takes {}'.format(t2 - t1)) return objective
def getALS_CG(T,U,V,W,regParam,omega,I,J,K,r): ''' Same thing as above, but CTF ''' it = 0 E = ctf.tensor((I,J,K)) E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W))*regParam while True: U = updateFactor_CG(T,U,V,W,regParam,omega,I,J,K,r,"U") V = updateFactor_CG(T,U,V,W,regParam,omega,I,J,K,r,"V") W = updateFactor_CG(T,U,V,W,regParam,omega,I,J,K,r,"W") E.set_zero() E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W))*regParam print(curr_err_norm, next_err_norm) if abs(curr_err_norm - next_err_norm) < .001 or it > 20: break #print(next_err_norm/curr_err_norm) curr_err_norm = next_err_norm it += 1 print("Number of iterations: ", it) return U,V,W
def getALSCtf(T,U,V,W,regParam,omega,I,J,K,r): ''' Same thing as above, but CTF ''' it = 0 E = ctf.tensor((I,J,K)) E.i("ijk") << T.i("ijk") - U.i("iu")*V.i("ju")*W.i("ku") curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W))*regParam while True: U = updateU(T,U,V,W,regParam,omega,I,J,K,r) V = updateV(T,U,V,W,regParam,omega,I,J,K,r) W = updateW(T,U,V,W,regParam,omega,I,J,K,r) E.set_zero() E.i("ijk") << T.i("ijk") - U.i("iu")*V.i("ju")*W.i("ku") next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W))*regParam if abs(curr_err_norm - next_err_norm) < .001 or it > 100: break print(curr_err_norm, next_err_norm) curr_err_norm = next_err_norm it += 1 print("Number of iterations: ", it) return U,V,W
def getALS_SVD(T, U, V, W, regParam, omega, I, J, K, r): it = 0 E = ctf.tensor((I, J, K)) E.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam while True: U = updateFactor_SVD(T, U, V, W, regParam, omega, I, J, K, r, "U") V = updateFactor_SVD(T, U, V, W, regParam, omega, I, J, K, r, "V") W = updateFactor_SVD(T, U, V, W, regParam, omega, I, J, K, r, "W") E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam if ctf.comm().rank() == 0: print(curr_err_norm, next_err_norm) if abs(curr_err_norm - next_err_norm) < .001 or it > 20: break curr_err_norm = next_err_norm it += 1 if ctf.comm().rank() == 0: print("Number of iterations: ", it) return U, V, W
def dense_GD(T, U, V, W, Lambda, I, J, K, r, stepSize): iteration_count = 0 E = ctf.tensor((I, J, K)) E.i("ijk") << T.i("ijk") - U.i("iu") * V.i("ju") * W.i("ku") curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda while True: U = dense_updateU(T, U, V, W, Lambda, I, J, K, r, E, stepSize) V = dense_updateV(T, U, V, W, Lambda, I, J, K, r, E, stepSize) W = dense_updateW(T, U, V, W, Lambda, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << T.i("ijk") - U.i("iu") * V.i("ju") * W.i("ku") next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda if abs(curr_err_norm - next_err_norm) < .001 or iteration_count > 100: break print(curr_err_norm, next_err_norm) curr_err_norm = next_err_norm iteration_count += 1 print("Number of iterations: ", iteration_count) return U, V, W
def test_svd_rand(self): m = 19 n = 15 k = 13 for dt in [numpy.float32, numpy.float64, numpy.complex64, numpy.complex128]: A = ctf.random.random((m,n)) A = ctf.astensor(A,dtype=dt) [U,S,VT]=ctf.svd_rand(A,k,5,1) self.assertTrue(allclose(ctf.eye(k),ctf.dot(U.T(),U))) self.assertTrue(allclose(ctf.eye(k),ctf.dot(VT,VT.T()))) [U2,S2,VT2]=ctf.svd(A,k) rs1 = ctf.vecnorm(A - ctf.dot(U*S,VT)) rs2 = ctf.vecnorm(A - ctf.dot(U2*S2,VT2)) rA = ctf.vecnorm(A) self.assertTrue(rs1 < rA) self.assertTrue(rs2 < rs1) self.assertTrue(numpy.abs(rs1 - rs2)<3.e-1)
def sparse_SGD(T, U, V, W, Lambda, omega, I, J, K, r, stepSize, sample_rate, num_iter, errThresh, time_limit, work_cycle, use_MTTKRP): times = [0 for i in range(7)] iteration_count = 0 total_count = 0 R = ctf.tensor((I, J, K), sp=T.sp) if T.sp == True: nnz_tot = T.nnz_tot else: nnz_tot = ctf.sum(omega) start_time = time.time() starting_time = time.time() dtime = 0 R.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") curr_err_norm = ctf.vecnorm(R) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda times[0] += time.time() - starting_time norm = [curr_err_norm] step = stepSize * 0.5 t_obj_calc = 0. while iteration_count < num_iter and time.time() - start_time - t_obj_calc < time_limit: iteration_count += 1 starting_time = time.time() sampled_T = T.copy() sampled_T.sample(sample_rate) times[1] += time.time() - starting_time sparse_update(sampled_T, [U, V, W], Lambda, [I, J, K], r, stepSize * 0.5 + step, sample_rate, times, use_MTTKRP) #step *= 0.99 sampled_T.set_zero() if iteration_count % work_cycle == 0: duration = time.time() - start_time - t_obj_calc t_b_obj = time.time() total_count += 1 R.set_zero() R.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") diff_norm = ctf.vecnorm(R) RMSE = diff_norm/(nnz_tot**.5) next_err_norm = diff_norm + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda if glob_comm.rank() == 0: print('Objective after',duration,'seconds (',iteration_count,'iterations) is: {}'.format(next_err_norm)) print('RMSE after',duration,'seconds (',iteration_count,'iterations) is: {}'.format(RMSE)) t_obj_calc += time.time() - t_b_obj if abs(curr_err_norm - next_err_norm) < errThresh: break curr_err_norm = next_err_norm norm.append(curr_err_norm) duration = time.time() - start_time - t_obj_calc if ctf.comm().rank() == 0: print('SGD amortized seconds per sweep: {}'.format(duration/(iteration_count*sample_rate))) print("Time/SGD iteration: {}".format(duration/iteration_count)) return norm
def sparse_SGD(T, U, V, W, Lambda, omega, I, J, K, r, stepSize, sample_rate): iteration_count = 0 E = ctf.tensor((I, J, K)) R = ctf.tensor((I, J, K)) R.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") sampled_T = ctf.tensor((I, J, K)) curr_err_norm = ctf.vecnorm(R) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda norm = [curr_err_norm] while True: random = ctf.tensor((I, J, K)) random.fill_random(0, 1) random = ((random > sample_rate) * ctf.astensor(1.)) sampled_T = T * random #sampled_T.sample(sample_rate) sampled_omega = getOmega(sampled_T) E.i("ijk") << sampled_T.i( "ijk") - sampled_omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") U = sparse_updateU(sampled_T, U, V, W, Lambda, sampled_omega, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << sampled_T.i( "ijk") - sampled_omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") V = sparse_updateV(sampled_T, U, V, W, Lambda, sampled_omega, I, J, K, r, E, stepSize) E.set_zero() E.i("ijk") << sampled_T.i( "ijk") - sampled_omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") W = sparse_updateW(sampled_T, U, V, W, Lambda, sampled_omega, I, J, K, r, E, stepSize) E.set_zero() sampled_T.set_zero() if iteration_count % 5 == 0: R.set_zero() R.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") diff_norm = ctf.vecnorm(R) next_err_norm = diff_norm + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * Lambda print(curr_err_norm, next_err_norm) print(diff_norm) if abs(curr_err_norm - next_err_norm) < .01 or iteration_count > 100: break curr_err_norm = next_err_norm norm.append(curr_err_norm) iteration_count += 1 print("Number of iterations: ", iteration_count) return norm
def test_tree_ctr(self): X = [] for i in range(10): X.append(ctf.random.random((8, 8))) scl = ctf.einsum("ab,ac,ad,ae,af,bg,cg,dg,eg,fg",X[0],X[1],X[2],X[3],X[4],X[5],X[6],X[7],X[8],X[9]) C = ctf.dot(X[0],X[5]) for i in range(1,5): C = C * ctf.dot(X[i],X[5+i]) scl2 = ctf.vecnorm(C,1) self.assertTrue(numpy.abs(scl-scl2)<1.e-4)
def test_cholesky(self): n = 4 for dt in [numpy.float32, numpy.float64]: A = ctf.random.random((n,n)) A = ctf.astensor(A,dtype=dt) A = ctf.dot(A.T(), A) L = ctf.cholesky(A) D = L.T() * L D.i("ii") << -1.0*L.i("ii")*L.i("ii") self.assertTrue(abs(ctf.vecnorm(D))<= 1.e-6) self.assertTrue(allclose(A, ctf.dot(L,L.T())))
def get_objective(T,U,V,W,omega,regParam): t_obj = ctf.timer("ccd_get_objective") t_obj.start() L = ctf.tensor(T.shape, sp=T.sp) t0 = time.time() L.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U,V,W]).i("ijk") t1 = time.time() normL = ctf.vecnorm(L) if T.sp == True: RMSE = normL/(T.nnz_tot**.5) else: nnz_tot = ctf.sum(omega) RMSE = normL/(nnz_tot**.5) objective = normL + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam t2 = time.time() if glob_comm.rank() == 0 and status_prints == True: print('generate L takes {}'.format(t1 - t0)) print('calc objective takes {}'.format(t2 - t1)) t_obj.stop() return [objective, RMSE]
def test_solve_tri(self): n = 4 m = 7 for dt in [numpy.float32, numpy.float64]: B = ctf.random.random((n,m)) B = ctf.astensor(B,dtype=dt) L = ctf.random.random((n,n)) L = ctf.astensor(L,dtype=dt) L = ctf.tril(L) D = L.T() * L D.i("ii") << -1.0*L.i("ii")*L.i("ii") self.assertTrue(abs(ctf.vecnorm(D))<= 1.e-6) X = ctf.solve_tri(L,B) self.assertTrue(allclose(B, ctf.dot(L,X))) U = ctf.random.random((n,n)) U = ctf.astensor(U,dtype=dt) U = ctf.triu(U) D = U.T() * U D.i("ii") << -1.0*U.i("ii")*U.i("ii") self.assertTrue(abs(ctf.vecnorm(D))<= 1.e-6) X = ctf.solve_tri(U,B,False) self.assertTrue(allclose(B, ctf.dot(U,X))) U = ctf.random.random((m,m)) U = ctf.astensor(U,dtype=dt) U = ctf.triu(U) D = U.T() * U D.i("ii") << -1.0*U.i("ii")*U.i("ii") self.assertTrue(abs(ctf.vecnorm(D))<= 1.e-6) X = ctf.solve_tri(U,B,False,False) self.assertTrue(allclose(B, ctf.dot(X,U))) U = ctf.random.random((m,m)) U = ctf.astensor(U,dtype=dt) U = ctf.triu(U) D = U.T() * U D.i("ii") << -1.0*U.i("ii")*U.i("ii") self.assertTrue(abs(ctf.vecnorm(D))<= 1.e-6) X = ctf.solve_tri(U,B,False,False,True) self.assertTrue(allclose(B, ctf.dot(X,U.T())))
def getALS_CG(T, U, V, W, regParam, omega, I, J, K, r, block): t0 = time.time() it = 0 E = ctf.tensor((I, J, K), sp=True) E.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") if ctf.comm().rank() == 0: print("contraction to form the error tensor cost %f seconds" % (np.round_(time.time() - t0, 4))) assert (E.sp == 1) curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam while True: t = time.time() U = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "U") assert (U.sp == 1) V = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "V") assert (V.sp == 1) W = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "W") assert (W.sp == 1) if ctf.comm().rank() == 0: print( "CG update factor matrices in the following iteration cost %f seconds" % np.round_(time.time() - t, 4)) E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") assert (E.sp == 1) next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam if ctf.comm().rank() == 0: print(curr_err_norm, next_err_norm) it += 1 if abs(curr_err_norm - next_err_norm) < .001 or it > 100: break curr_err_norm = next_err_norm nt = np.round_(time.time() - t0, 4) return it, nt
def test_sparse_SY(self): A = ctf.tensor((4, 4), sym=[ctf.SYM.SY, ctf.SYM.NS]) AA = ctf.tensor((3, 3, 3), sym=[ctf.SYM.NS, ctf.SYM.SY, ctf.SYM.NS]) B = ctf.tensor((4, 4, 4, 4), sym=[ctf.SYM.NS, ctf.SYM.NS, ctf.SYM.SY, ctf.SYM.NS]) C = ctf.tensor((4, 4, 4, 4), sym=[ctf.SYM.SY, ctf.SYM.NS, ctf.SYM.NS, ctf.SYM.NS]) D = ctf.tensor((4, 4, 4, 4), sym=[ctf.SYM.SY, ctf.SYM.NS, ctf.SYM.SY, ctf.SYM.NS]) E = ctf.tensor((4, 4, 4, 4), sym=[ctf.SYM.SY, ctf.SYM.SY, ctf.SYM.SY, ctf.SYM.NS]) for X in [A, AA, B, C, D, E]: X.fill_random(1., 1.) Y = X.sparsify(0.) #print("TEST") #print(X.shape,X.sym) #print(X) #print("norms are",ctf.vecnorm(X),ctf.vecnorm(Y)) self.assertTrue(allclose(X, Y)) self.assertTrue(allclose(X - Y, 0.)) self.assertTrue(allclose(ctf.vecnorm(X), ctf.vecnorm(Y)))
def getALS_CG(T, U, V, W, regParam, omega, I, J, K, r, block): it = 0 E = ctf.tensor((I, J, K), sp=True) E.i("ijk" ) << T.i("ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") NNZ = T.read_local_nnz()[1].shape[ 0] # number of nonzero entries, i.e. sample size curr_err_norm = ( ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam) / NNZ norm = [curr_err_norm] timeList = [0] t = time.time() while True: U = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "U") V = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "V") W = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "W") E.set_zero() E.i("ijk") << T.i( "ijk") - omega.i("ijk") * U.i("iu") * V.i("ju") * W.i("ku") next_err_norm = (ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam) / NNZ if ctf.comm().rank() == 0: print(curr_err_norm, next_err_norm) if abs(curr_err_norm - next_err_norm) < .0001 or it > 100: break curr_err_norm = next_err_norm norm.append(curr_err_norm) timeList.append(np.round_(time.time() - t, 4)) it += 1 return norm, it, timeList
def getALS_CG(T, U, V, W, regParam, omega, I, J, K, r, block): it = 0 E = ctf.tensor((I, J, K), sp=True) #E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") E.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") assert (E.sp == 1) curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam t = time.time() while True: U = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "U") assert (U.sp == 1) V = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "V") assert (V.sp == 1) W = updateFactor_CG(T, U, V, W, regParam, omega, I, J, K, r, block, "W") assert (W.sp == 1) E.set_zero() #E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") E.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") assert (E.sp == 1) next_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam if ctf.comm().rank() == 0: print(curr_err_norm, next_err_norm) it += 1 if abs(curr_err_norm - next_err_norm) < .001 or it > 100: break curr_err_norm = next_err_norm nt = np.round_(time.time() - t, 4) return it, nt
def test_tsvd(self): lens = [4,5,6,3] for dt in [numpy.float32, numpy.float64, numpy.complex64, numpy.complex128]: A = ctf.tensor(lens,dtype=dt) A.fill_random() [U,S,VT]=A.i("ijkl").svd("ija","akl") A.i("ijkl") << -1.0*U.i("ija")*S.i("a")*VT.i("akl") self.assertTrue(ctf.vecnorm(A)/A.tot_size()<1.e-6) A = ctf.tensor(lens,dtype=dt) A.fill_random() [U,S,VT]=A.i("ijkl").svd("ika","ajl") A.i("ijkl") << -1.0*U.i("ika")*S.i("a")*VT.i("ajl") self.assertTrue(ctf.vecnorm(A)/A.tot_size()<1.e-6) A = ctf.tensor(lens,dtype=dt) A.fill_random() [U,S,VT]=A.i("ijkl").svd("ika","ajl") [U,S1,VT]=A.i("ijkl").svd("ika","ajl",4) [U,S2,VT]=A.i("ijkl").svd("ika","ajl",4,numpy.abs(S[3])*(1.-1.e-5)) self.assertTrue(allclose(S1,S2)) [U,S2,VT]=A.i("ijkl").svd("ika","ajl",4,numpy.abs(S[2])) self.assertTrue(not allclose(S1.shape,S2.shape)) [U,S2,VT]=A.i("ijkl").svd("ika","ajl",4,numpy.abs(S[5])) self.assertTrue(allclose(S1,S2)) [U,S,VT]=A.i("ijkl").svd("iakj","la") A.i("ijkl") << -1.0*U.i("iakj")*S.i("a")*VT.i("la") self.assertTrue(ctf.vecnorm(A)/A.tot_size()<1.e-6) A.fill_random() [U,S,VT]=A.i("ijkl").svd("alk","jai") A.i("ijkl") << -1.0*U.i("alk")*S.i("a")*VT.i("jai") self.assertTrue(ctf.vecnorm(A)/A.tot_size()<1.e-6) K = ctf.tensor((U.shape[0],U.shape[0]),dtype=dt) K.i("ab") << U.i("alk") * U.i("blk") self.assertTrue(allclose(K,ctf.eye(U.shape[0]))) 0.*K.i("ab") << VT.i("jai") * VT.i("jbi") self.assertTrue(allclose(K,ctf.eye(U.shape[0]))) A.fill_random() [U,S,VT]=A.i("ijkl").svd("alk","jai",4,0,True) nrm1 = ctf.vecnorm(A) A.i("ijkl") << -1.0*U.i("alk")*S.i("a")*VT.i("jai") self.assertTrue(ctf.vecnorm(A)<nrm1) K = ctf.tensor((U.shape[0],U.shape[0]),dtype=dt) K.i("ab") << U.i("alk") * U.i("blk") self.assertTrue(allclose(K,ctf.eye(U.shape[0]))) 0.*K.i("ab") << VT.i("jai") * VT.i("jbi") self.assertTrue(allclose(K,ctf.eye(U.shape[0]))) T = ctf.tensor((4,3,6,5,1,7),dtype=dt) [U,S,VT] = T.i("abcdef").svd("crd","aerfb") T.i("abcdef") << -1.0*U.i("crd")*S.i("r")*VT.i("aerfb") self.assertTrue(ctf.vecnorm(T)/T.tot_size()<1.e-6) K = ctf.tensor((S.shape[0],S.shape[0]),dtype=dt) K.i("rs") << U.i("crd")*U.i("csd") self.assertTrue(allclose(K,ctf.eye(S.shape[0]))) K = ctf.tensor((S.shape[0],S.shape[0]),dtype=dt) K.i("rs") << VT.i("aerfb")*VT.i("aesfb") self.assertTrue(allclose(K,ctf.eye(S.shape[0])))
eris.oooo = eris.oooo.sparsify(cutoff) eris.ooov = eris.ooov.sparsify(cutoff) eris.vvvv = eris.vvvv.sparsify(cutoff) eris.ovov = eris.ovov.sparsify(cutoff) if (ctf.comm().rank() == 0): for e in [ eris.ovvv, eris.oovv, eris.oooo, eris.ooov, eris.vvvv, eris.ovov ]: print "For integral tensor with shape", e.shape, "symmetry", e.sym, "number of nonzeros with cutoff", cutoff, "is ", ( int(10000000 * e.nnz_tot / e.size)) / 100000., "%" t1 = ctf.zeros([nocc, nvir]) t2 = ctf.zeros([nocc, nocc, nvir, nvir]) t2.fill_random(0., 1.) if (cutoff != None): t2 = t2.sparsify(1 - (1 - cutoff) * 10) if (ctf.comm().rank() == 0): print "For amplitude tensor with shape", t2.shape, "symmetry", t2.sym, "number of nonzeros with cutoff", 1 - ( 1 - cutoff) * 10, "is ", (int( 10000000 * t2.nnz_tot / t2.size)) / 100000., "%" start = time.time() [t1new, t2new] = update_amps(t1, t2, eris) end = time.time() t1norm = ctf.vecnorm(t1new) t2norm = ctf.vecnorm(t2new) if (ctf.comm().rank() == 0): print "t1 norm is", t1norm, "t2 norm is", t2norm print "CCSD iteration time was", end - start, "sec"
def getALS_CG(T, U, V, W, regParam, omega, I, J, K, r, block_size, num_iter=100, err_thresh=.001, time_limit=600, use_implicit=True): if use_implicit == True: t_ALS_CG = ctf.timer_epoch("als_CG_implicit") if ctf.comm().rank() == 0: print( "--------------------------------ALS with implicit CG------------------------" ) else: t_ALS_CG = ctf.timer_epoch("als_CG_explicit") if ctf.comm().rank() == 0: print( "--------------------------------ALS with explicit CG------------------------" ) if T.sp == True: nnz_tot = T.nnz_tot else: nnz_tot = ctf.sum(omega) t_ALS_CG.begin() it = 0 if block_size <= 0: block_size = max(I, J, K) t_init_error_norm = ctf.timer("ALS_init_error_tensor_norm") t_init_error_norm.start() t0 = time.time() E = ctf.tensor((I, J, K), sp=T.sp) #E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") E.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") t1 = time.time() curr_err_norm = ctf.vecnorm(E) + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam t2 = time.time() t_init_error_norm.stop() if ctf.comm().rank() == 0 and status_prints == True: print('ctf.TTTP() takes {}'.format(t1 - t0)) print('ctf.vecnorm {}'.format(t2 - t1)) t_before_loop = time.time() t_obj_calc = 0. ctf.random.seed(42) while True: t_upd_cg = ctf.timer("ALS_upd_cg") t_upd_cg.start() U = updateFactor(T, U, V, W, regParam, omega, I, J, K, r, block_size, "U", use_implicit) V = updateFactor(T, U, V, W, regParam, omega, I, J, K, r, block_size, "V", use_implicit) W = updateFactor(T, U, V, W, regParam, omega, I, J, K, r, block_size, "W", use_implicit) duration = time.time() - t_before_loop - t_obj_calc t_b_obj = time.time() E.set_zero() #E.i("ijk") << T.i("ijk") - omega.i("ijk")*U.i("iu")*V.i("ju")*W.i("ku") E.i("ijk") << T.i("ijk") - ctf.TTTP(omega, [U, V, W]).i("ijk") diff_norm = ctf.vecnorm(E) RMSE = diff_norm / (nnz_tot**.5) next_err_norm = diff_norm + (ctf.vecnorm(U) + ctf.vecnorm(V) + ctf.vecnorm(W)) * regParam t_obj_calc += time.time() - t_b_obj t_upd_cg.stop() it += 1 if ctf.comm().rank() == 0: #print("Last residual:",curr_err_norm,"New residual",next_err_norm) print('Objective after', duration, 'seconds (', it, 'iterations) is: {}'.format(next_err_norm)) print('RMSE after', duration, 'seconds (', it, 'iterations) is: {}'.format(RMSE)) if abs(curr_err_norm - next_err_norm ) < err_thresh or it >= num_iter or duration > time_limit: break curr_err_norm = next_err_norm t_ALS_CG.end() duration = time.time() - t_before_loop - t_obj_calc if glob_comm.rank() == 0: print('ALS (implicit =', use_implicit, ') time per sweep: {}'.format(duration / it))
def CG(A, b, x0, r, regParam, I, is_implicit=False): t_batch_cg = ctf.timer("ALS_exp_cg") t_batch_cg.start() Ax0 = ctf.tensor((I, r)) if is_implicit: Ax0.i("ir") << A.mul("ir", x0) else: Ax0.i("ir") << A.i("irl") * x0.i("il") Ax0 += regParam * x0 rk = b - Ax0 sk = rk xk = x0 for i in range(sk.shape[-1]): # how many iterations? Ask = ctf.tensor((I, r)) t_cg_bmvec = ctf.timer("ALS_exp_cg_mvec") t_cg_bmvec.start() t0 = time.time() if is_implicit: Ask.i("ir") << A.mul("ir", sk) else: Ask.i("ir") << A.i("irl") * sk.i("il") t1 = time.time() if ctf.comm().rank == 0 and status_prints == True: print('form Ask takes {}'.format(t1 - t0)) t_cg_bmvec.stop() Ask += regParam * sk rnorm = ctf.tensor(I) rnorm.i("i") << rk.i("ir") * rk.i("ir") skAsk = ctf.tensor(I) skAsk.i("i") << sk.i("ir") * Ask.i("ir") alpha = rnorm / (skAsk + 1.e-30) alphask = ctf.tensor((I, r)) alphask.i("ir") << alpha.i("i") * sk.i("ir") xk1 = xk + alphask alphaask = ctf.tensor((I, r)) alphaask.i("ir") << alpha.i("i") * Ask.i("ir") rk1 = rk - alphaask rk1norm = ctf.tensor(I) rk1norm.i("i") << rk1.i("ir") * rk1.i("ir") beta = rk1norm / (rnorm + 1.e-30) betask = ctf.tensor((I, r)) betask.i("ir") << beta.i("i") * sk.i("ir") sk1 = rk1 + betask rk = rk1 xk = xk1 sk = sk1 if ctf.vecnorm(rk) < CG_thresh: break #print("explicit CG residual after",sk.shape[-1],"iterations is",ctf.vecnorm(rk)) t_batch_cg.stop() return xk
def vecnorm(T): return ctf.vecnorm(T)
def _make_eris(mycc, mo_coeff=None, cutoff=None): mol = mycc.mol NS = ctf.SYM.NS SY = ctf.SYM.SY eris = ccsd._ChemistsERIs() if mo_coeff is None: mo_coeff = mycc.mo_coeff eris.mo_coeff = ccsd._mo_without_core(mycc, mo_coeff) nao, nmo = eris.mo_coeff.shape nocc = mycc.nocc nvir = nmo - nocc nvir_pair = nvir * (nvir + 1) // 2 nao_pair = nao * (nao + 1) // 2 mo = ctf.astensor(eris.mo_coeff) ppoo, ppov, ppvv = _make_ao_ints(mol, eris.mo_coeff, nocc) eris.nocc = mycc.nocc eris.mol = mycc.mol eris.fock = ctf.tensor((nmo, nmo)) with omp(16): if rank == 0: dm = mycc._scf.make_rdm1(mycc.mo_coeff, mycc.mo_occ) fockao = mycc._scf.get_hcore() + mycc._scf.get_veff(mycc.mol, dm) fock = reduce(numpy.dot, (eris.mo_coeff.T, fockao, eris.mo_coeff)) eris.fock.write(numpy.arange(nmo**2), fock.ravel()) else: eris.fock.write([], []) orbo = mo[:, :nocc] orbv = mo[:, nocc:] if (ctf.comm().rank() == 0): print 'before contraction', rank, lib.current_memory() tmp = ctf.tensor([nao, nocc, nvir, nvir], sym=[NS, NS, SY, NS]) otmp = ctf.einsum('pqrs,qj->pjrs', ppvv, orbo, out=tmp) eris.oovv = ctf.tensor([nocc, nocc, nvir, nvir], sym=[NS, NS, SY, NS]) eris.ovvv = ctf.einsum('pjrs,pi->ijrs', otmp, orbo, out=eris.oovv) otmp = tmp = None if (ctf.comm().rank() == 0): print '___________ vvvv', rank, lib.current_memory() tmp = ctf.tensor([nao, nvir, nvir, nvir], sym=[NS, NS, SY, NS]) if (ctf.comm().rank() == 0): print '___________ vvvv sub1', rank, lib.current_memory() vtmp = ctf.einsum('pqrs,qj->pjrs', ppvv, orbv, out=tmp) eris.ovvv = ctf.tensor([nocc, nvir, nvir, nvir], sym=[NS, NS, SY, NS]) eris.ovvv = ctf.einsum('pjrs,pi->ijrs', vtmp, orbo, out=eris.ovvv) ppvv = None tmp = ctf.tensor([nvir, nvir, nvir, nvir], sym=[NS, NS, SY, NS]) if (ctf.comm().rank() == 0): print '___________ vvvv sub2', rank, lib.current_memory() vtmp = ctf.einsum('pjrs,pi->ijrs', vtmp, orbv, out=tmp) eris.vvvv = ctf.tensor(sym=[SY, NS, SY, NS], copy=vtmp) vtmp = tmp = None vtmp = ctf.einsum('pqrs,qj->pjrs', ppov, orbv) eris.ovov = ctf.einsum('pjrs,pi->ijrs', vtmp, orbo) vtmp = None otmp = ctf.einsum('pqrs,qj->pjrs', ppov, orbo) eris.ooov = ctf.einsum('pjrs,pi->ijrs', otmp, orbo) ppov = otmp = None otmp = ctf.einsum('pqrs,qj->pjrs', ppoo, orbo) eris.oooo = ctf.einsum('pjrs,pi->ijrs', otmp, orbo) ppoo = otmp = None if cutoff != None: print("Using cutoff", cutoff) eris.ovvv = eris.ovvv.sparsify(ctf.vecnorm(eris.ovvv) * cutoff) eris.oovv = eris.oovv.sparsify(ctf.vecnorm(eris.oovv) * cutoff) eris.oooo = eris.oooo.sparsify(ctf.vecnorm(eris.oooo) * cutoff) eris.ooov = eris.ooov.sparsify(ctf.vecnorm(eris.ooov) * cutoff) eris.vvvv = eris.vvvv.sparsify(ctf.vecnorm(eris.vvvv) * cutoff) eris.ovov = eris.ovov.sparsify(ctf.vecnorm(eris.ovov) * cutoff) if (ctf.comm().rank() == 0): for e in [ eris.ovvv, eris.oovv, eris.oooo, eris.ooov, eris.vvvv, eris.ovov ]: print "For integral tensor with shape,", e.shape, "symmetry", e.sym, "number of nonzeros with cutoff", cutoff, "is ", ( int(100000 * e.nnz_tot / e.size)) / 1000, "%" if (ctf.comm().rank() == 0): print '___________ fock', rank, lib.current_memory() eris.mo_energy = eris.fock.diagonal() eris.foo = eris.fock[:nocc, :nocc].copy() eris.foo.i('ii') << (eris.mo_energy[:nocc] * -1).i('i') eris.fvv = eris.fock[nocc:, nocc:].copy() eris.fvv.i('ii') << (eris.mo_energy[nocc:] * -1).i('i') eris.fov = ctf.astensor(eris.fock[:nocc, nocc:]) return eris