SPLATT is a toolkit of parallel software for sparse tensor factorization developed at the University of Minnesota. SPLATT ships with an executable, an Octave/Matlab API, and a C/C++ API.

Check SPLATT out on Github. The latest developments (including tensor completion) can be found there on the 'sc16' branch. New packaged release coming soon!

Current source release: splatt-1.1.1.tgz

SPLATT requires CMake and a compiler with OpenMP support. Most testing has been conducted with recent GCC. Please email us if you have issues building SPLATT.

After downloading and extracting, see the file README.md for build and installation instructions.

Binary Executable

splatt-check finds some errors in tensors such as empty slices and duplicate nonzero entries. Empty slices are indices which do not have any nonzero entries associated with them. Some SPLATT routines (including splatt-cpd) expect there to be no empty slices, so running splatt-check on a new tensor is recommended.

  $ splatt check mytensor.tns --fix=mytensor.fixed.tns

splatt-cpd finds the CPD of a sparse tensor. The matrix factors are written to files "modeN.mat" and "lambda.mat". This example computes a rank-25 CPD.

  $ splatt cpd mytensor.tns -r 25

GNU Octave/Matlab

Several SPLATT routines can be used in your Octave/Matlab applications. splatt-cpd is easily accessed:

  K = splatt_cpd('mytensor.tns', 25);

  opts = struct('tol', 1e-6, 'its', 100);
  K2 = splatt_cpd('mytensor.tns', 25, opts);

splatt-mttkrp and other routines are also available for users developing their own tensor factorizations.

  % load the tensor to avoid repeated IO costs
  X = splatt_load('mytensor.tns');

  % access the dimensions of the tensor
  nfactors = 50;
  nmodes = length(splatt_dim(X));
  for m = 1:nmodes
    mats{m} = rand(splatt_dim(X,m), nfactors);
  end

  % MTTKRP
  for m = 1:nmodes
    mats{m} = splatt_mttkrp(X, mats, m);
  end

C/C++

SPLATT can also be used directly in your C/C++ application.

  /* allocate default options */
  double * splatt_opts = splatt_default_opts();
  /* set tolerance for convergence and the maximum iterations */
  splatt_opts[SPLATT_OPTION_TOLERANCE] = 1e-5;
  splatt_opts[SPLATT_OPTION_NITER] = 100;

  splatt_idx_t nmodes;
  splatt_csf_t * tt;
  /* load the tensor from a file */
  int ret = splatt_csf_load("mytensor.tns", &nmodes, &tt, splatt_opts);
  if(ret != SPLATT_SUCCESS) {
    /* error! */
  }

  /* do the factorization! */
  splatt_idx_t nfactors = 10;
  splatt_kruskal_t factored;
  ret = splatt_cpd_als(tt, nfactors, cpd_opts, &factored);
  if(ret != SPLATT_SUCCESS) {
    /* error! */
  }

  for(splatt_idx_t m = 0; m < nmodes; ++m) {
    /* access factored.lambda and factored.factors[m]. Stored row-major! */
  }

  /* cleanup */
  splatt_free_csf(tt, cpd_opts);
  splatt_free_kruskal(&factored);
  splatt_free_opts(cpd_opts);