nd4j-backends/nd4j-backend-impls/nd4j-cuda/src/main/java/org/nd4j/linalg/jcublas/blas/JcublasLapack.java
@Override
    public void spotrf(byte uplo, int N, INDArray A, INDArray INFO) {
        INDArray a = A;

        if (Nd4j.dataType() != DataBuffer.Type.FLOAT)
            log.warn("DOUBLE potrf called in FLOAT environment");

        if (A.ordering() == 'c')
            a = A.dup('f');

        if (Nd4j.getExecutioner() instanceof GridExecutioner)
            ((GridExecutioner) Nd4j.getExecutioner()).flushQueue();

        // Get context for current thread
        CudaContext ctx = (CudaContext) allocator.getDeviceContext().getContext();

        // setup the solver handles for cuSolver calls
        cusolverDnHandle_t handle = ctx.getSolverHandle();
        cusolverDnContext solverDn = new cusolverDnContext(handle);

        // synchronized on the solver
        synchronized (handle) {
            int result = cusolverDnSetStream(new cusolverDnContext(handle), new CUstream_st(ctx.getOldStream()));
            if (result != 0)
                throw new BlasException("solverSetStream failed");

            // transfer the INDArray into GPU memory
            CublasPointer xAPointer = new CublasPointer(a, ctx);

            // this output - indicates how much memory we'll need for the real operation
            DataBuffer worksizeBuffer = Nd4j.getDataBufferFactory().createInt(1);

            int stat = cusolverDnSpotrf_bufferSize(solverDn, uplo, N, 
                        (FloatPointer) xAPointer.getDevicePointer(), N,
                        (IntPointer) worksizeBuffer.addressPointer() // we intentionally use host pointer here
            );

            if (stat != CUSOLVER_STATUS_SUCCESS) {
                throw new BlasException("cusolverDnSpotrf_bufferSize failed", stat);
            }

            int worksize = worksizeBuffer.getInt(0);
            // Now allocate memory for the workspace, the permutation matrix and a return code
            Pointer workspace = new Workspace(worksize * Nd4j.sizeOfDataType());

            // Do the actual decomp
            stat = cusolverDnSpotrf(solverDn, uplo, N, 
                            (FloatPointer) xAPointer.getDevicePointer(), N,
                            new CudaPointer(workspace).asFloatPointer(),
                            worksize,
                            new CudaPointer(allocator.getPointer(INFO, ctx)).asIntPointer()
                            );

            if (stat != CUSOLVER_STATUS_SUCCESS) {
                throw new BlasException("cusolverDnSpotrf failed", stat);
            }
        }
        allocator.registerAction(ctx, a);
        allocator.registerAction(ctx, INFO);

        if (a != A)
            A.assign(a);

        if( uplo == 'U' ) {		
            A.assign( A.transpose() ) ;	
			INDArrayIndex ix[] = new INDArrayIndex[ 2 ] ;
			for( int i=1 ; i<Math.min( A.rows(), A.columns() ) ; i++ ) {
				ix[0] = NDArrayIndex.point( i ) ;
				ix[1] = NDArrayIndex.interval( 0, i ) ;				
				A.put(ix, 0) ;
			}            
        } else {
            INDArrayIndex ix[] = new INDArrayIndex[ 2 ] ;
            for( int i=0 ; i<Math.min( A.rows(), A.columns()-1 ) ; i++ ) {
                ix[0] = NDArrayIndex.point( i ) ;
                ix[1] = NDArrayIndex.interval( i+1, A.columns() ) ;
                A.put(ix, 0) ;
            }        
        }

        log.info("A: {}", A);
    }
@Override
    public void spotrf(byte uplo, int N, INDArray A, INDArray INFO) {
        INDArray a = A;

        if (Nd4j.dataType() != DataBuffer.Type.FLOAT)
            log.warn("DOUBLE potrf called in FLOAT environment");

        if (A.ordering() == 'c')
            a = A.dup('f');

        if (Nd4j.getExecutioner() instanceof GridExecutioner)
            ((GridExecutioner) Nd4j.getExecutioner()).flushQueue();

        // Get context for current thread
        CudaContext ctx = (CudaContext) allocator.getDeviceContext().getContext();

        // setup the solver handles for cuSolver calls
        cusolverDnHandle_t handle = ctx.getSolverHandle();
        cusolverDnContext solverDn = new cusolverDnContext(handle);

        // synchronized on the solver
        synchronized (handle) {
            int result = cusolverDnSetStream(new cusolverDnContext(handle), new CUstream_st(ctx.getOldStream()));
            if (result != 0)
                throw new BlasException("solverSetStream failed");

            // transfer the INDArray into GPU memory
            CublasPointer xAPointer = new CublasPointer(a, ctx);

            // this output - indicates how much memory we'll need for the real operation
            DataBuffer worksizeBuffer = Nd4j.getDataBufferFactory().createInt(1);

            int stat = cusolverDnSpotrf_bufferSize(solverDn, uplo, N, 
                        (FloatPointer) xAPointer.getDevicePointer(), N,
                        (IntPointer) worksizeBuffer.addressPointer() // we intentionally use host pointer here
            );

            if (stat != CUSOLVER_STATUS_SUCCESS) {
                throw new BlasException("cusolverDnSpotrf_bufferSize failed", stat);
            }

            int worksize = worksizeBuffer.getInt(0);
            // Now allocate memory for the workspace, the permutation matrix and a return code
            Pointer workspace = new Workspace(worksize * Nd4j.sizeOfDataType());

            // Do the actual decomp
            stat = cusolverDnSpotrf(solverDn, uplo, N, 
                            (FloatPointer) xAPointer.getDevicePointer(), N,
                            new CudaPointer(workspace).asFloatPointer(),
                            worksize,
                            new CudaPointer(allocator.getPointer(INFO, ctx)).asIntPointer()
                            );

            if (stat != CUSOLVER_STATUS_SUCCESS) {
                throw new BlasException("cusolverDnSpotrf failed", stat);
            }
        }
        allocator.registerAction(ctx, a);
        allocator.registerAction(ctx, INFO);

        if (a != A)
            A.assign(a);

        if( uplo == 'U' ) {		
            A.assign( A.transpose() ) ;	
			INDArrayIndex ix[] = new INDArrayIndex[ 2 ] ;
			for( int i=1 ; i<Math.min( A.rows(), A.columns() ) ; i++ ) {
				ix[0] = NDArrayIndex.point( i ) ;
				ix[1] = NDArrayIndex.interval( 0, i ) ;				
				A.put(ix, 0) ;
			}            
        } else {
            INDArrayIndex ix[] = new INDArrayIndex[ 2 ] ;
            for( int i=0 ; i<Math.min( A.rows(), A.columns()-1 ) ; i++ ) {
                ix[0] = NDArrayIndex.point( i ) ;
                ix[1] = NDArrayIndex.interval( i+1, A.columns() ) ;
                A.put(ix, 0) ;
            }        
        }

        log.info("A: {}", A);
    }
@ Override public void spotrf ( byte uplo , int N , INDArray A , INDArray INFO ) { INDArray a = A ; if ( Nd4j . dataType ( ) != DataBuffer . Type . FLOAT ) log . warn ( "DOUBLE potrf called in FLOAT environment" ) ; if ( A . ordering ( ) == ' ' ) a = A . dup ( ' ' ) ; if ( Nd4j . getExecutioner ( ) instanceof GridExecutioner ) ( ( GridExecutioner ) Nd4j . getExecutioner ( ) ) . flushQueue ( ) ; // Get context for current thread CudaContext ctx = ( CudaContext ) allocator . getDeviceContext ( ) . getContext ( ) ; // setup the solver handles for cuSolver calls cusolverDnHandle_t handle = ctx . getSolverHandle ( ) ; cusolverDnContext solverDn = new cusolverDnContext ( handle ) ; // synchronized on the solver synchronized ( handle ) { int result = cusolverDnSetStream ( new cusolverDnContext ( handle ) , new CUstream_st ( ctx . getOldStream ( ) ) ) ; if ( result != 0 ) throw new BlasException ( "solverSetStream failed" ) ; // transfer the INDArray into GPU memory CublasPointer xAPointer = new CublasPointer ( a , ctx ) ; // this output - indicates how much memory we'll need for the real operation DataBuffer worksizeBuffer = Nd4j . getDataBufferFactory ( ) . createInt ( 1 ) ; int stat = cusolverDnSpotrf_bufferSize ( solverDn , uplo , N , ( FloatPointer ) xAPointer . getDevicePointer ( ) , N , ( IntPointer ) worksizeBuffer . addressPointer ( ) // we intentionally use host pointer here ) ; if ( stat != CUSOLVER_STATUS_SUCCESS ) { throw new BlasException ( "cusolverDnSpotrf_bufferSize failed" , stat ) ; } int worksize = worksizeBuffer . getInt ( 0 ) ; // Now allocate memory for the workspace, the permutation matrix and a return code Pointer workspace = new Workspace ( worksize * Nd4j . sizeOfDataType ( ) ) ; // Do the actual decomp stat = cusolverDnSpotrf ( solverDn , uplo , N , ( FloatPointer ) xAPointer . getDevicePointer ( ) , N , new CudaPointer ( workspace ) . asFloatPointer ( ) , worksize , new CudaPointer ( allocator . getPointer ( INFO , ctx ) ) . asIntPointer ( ) ) ; if ( stat != CUSOLVER_STATUS_SUCCESS ) { throw new BlasException ( "cusolverDnSpotrf failed" , stat ) ; } } allocator . registerAction ( ctx , a ) ; allocator . registerAction ( ctx , INFO ) ; if ( a != A ) A . assign ( a ) ; if ( uplo == ' ' ) { A . assign ( A . transpose ( ) ) ; INDArrayIndex ix [ ] = new INDArrayIndex [ 2 ] ; for ( int i = 1 ; i < Math . min ( A . rows ( ) , A . columns ( ) ) ; i ++ ) { ix [ 0 ] = NDArrayIndex . point ( i ) ; ix [ 1 ] = NDArrayIndex . interval ( 0 , i ) ; A . put ( ix , 0 ) ; } } else { INDArrayIndex ix [ ] = new INDArrayIndex [ 2 ] ; for ( int i = 0 ; i < Math . min ( A . rows ( ) , A . columns ( ) - 1 ) ; i ++ ) { ix [ 0 ] = NDArrayIndex . point ( i ) ; ix [ 1 ] = NDArrayIndex . interval ( i + 1 , A . columns ( ) ) ; A . put ( ix , 0 ) ; } } log . info ( "A: {}" , A ) ; }
CHOLESKY DECOMP
CHOLESKY DECOMP