code: def test_dot_synthetic():
      """benchmark mx.nd.dot(sparse_ndarray, dense_ndarray) with given density.
      `t_sparse` is the time cost of dot(csr, dns), while `t_dense` is the time cost
      of dot(dns, dns), with the same matrix except that it is in default storage type.
      """
  
      def measure_cost_forward_baseline(repeat, dot, lhs, rhs):
          start = time.time()
          for i in range(repeat):
              dot(lhs, rhs)
          end = time.time()
          diff = end - start
          return diff / repeat
  
      def measure_cost_backward_baseline(
          repeat, dot, transpose, lhs, rhs
      ):
          start = time.time()
          for i in range(repeat):
              dot(transpose(lhs), rhs)
          end = time.time()
          diff = end - start
          return diff / repeat
  
      def bench_dot_forward(m, k, n, density, ctx, repeat):
          set_default_device(ctx)
          dns = mx.nd.random.uniform(shape=(k, n)).copyto(ctx)
          data_shape = (m, k)
          csr_data = rand_ndarray(data_shape, "csr", density)
          dns_data = csr_data.tostype("default")
          rhs_dns_np = dns.asnumpy()
          lhs_csr_sp = sp.csr_matrix(dns_data.asnumpy())  # csr in scipy
          lhs_dns_np = lhs_csr_sp.tostype("default")
  
          data = [dns_data, csr_data]
          costs = []
          for d in data:
              dns.wait_to_read()
              d.wait_to_read()
              cost = measure_cost(repeat, mx.nd.dot, d, dns)
              costs.append(cost)
          ratio = costs[0] / costs[1]
  
          costs_baseline = []
          cost = measure_cost_forward_baseline(
              repeat, np.dot, lhs_dns_np, rhs_dns_np
          )
          costs_baseline.append(cost)
          cost = measure_cost_forward_baseline(
              repeat, sp.spmatrix.dot, lhs_csr_sp, rhs_dns_np
          )
          costs_baseline.append(cost)
          ratio_baseline = costs_baseline[0] / costs_baseline[1]
          fmt = "{:0.1f}\t\t{}\t{}\t{}\t{}\t{:0.2f}\t\t\t{:0.2f}\t{:0.5f}\t\t{:0.2f}\t\t\t\t{:0.6f}\t{:0.5f}"
          print(
              fmt.format(
                  density * 100,
                  str(ctx),
                  n,
                  m,
                  k,
                  ratio,
                  costs[0],
                  costs[1],
                  ratio_baseline,
                  costs_baseline[0],
                  costs_baseline[1],
              )
          )
  
      def bench_dot_backward(m, k, n, density, ctx, repeat):
          set_default_device(ctx)
          dns = mx.nd.random.uniform(shape=(m, n)).copyto(ctx)
          data_shape = (m, k)
          csr_data = rand_ndarray(data_shape, "csr", density)
          dns_data = csr_data.tostype("default")
          rhs_dns_np = dns.asnumpy()
          lhs_csr_sp = sp.csr_matrix(dns_data.asnumpy())
          lhs_dns_np = lhs_csr_sp.tostype("default")
  
          data = [dns_data, csr_data]
          costs = []
          for d in data:
              dns.wait_to_read()
              d.wait_to_read()
              cost = measure_cost(
                  repeat, mx.nd.dot, d, dns, transpose_a=True
              )
              costs.append(cost)
          ratio = costs[0] / costs[1]
  
          costs_baseline = []
          cost = measure_cost_backward_baseline(
              repeat, np.dot, np.transpose, lhs_dns_np, rhs_dns_np
          )
          costs_baseline.append(cost)
          cost = measure_cost_backward_baseline(
              repeat,
              sp.spmatrix.dot,
              sp.spmatrix.transpose,
              lhs_csr_sp,
              rhs_dns_np,
          )
          costs_baseline.append(cost)
          ratio_baseline = costs_baseline[0] / costs_baseline[1]
          fmt = "{:0.1f}\t\t{}\t{}\t{}\t{}\t{:0.2f}\t\t\t{:0.2f}\t{:0.5f}\t\t{:0.2f}\t\t\t\t{:0.6f}\t{:0.5f}"
          print(
              fmt.format(
                  density * 100,
                  str(ctx),
                  n,
                  m,
                  k,
                  ratio,
                  costs[0],
                  costs[1],
                  ratio_baseline,
                  costs_baseline[0],
                  costs_baseline[1],
              )
          )
  
      print("A = sparse NDArray of shape(m, k)")
      print("B = dense NDArray of shape(k, n)")
      print("dot_forward\tdot(csr, dns)")
      print(
          "density(%)\tcontext\tn\tm\tk\tt_dense/t_sparse\tt_dense\tt_sparse"
          "\tt_scipy_dense/t_scipy_sparse\tt_scipy_dense\tt_scipy_sparse"
      )
  
      check_call(
          _LIB.MXSetNumOMPThreads(ctypes.c_int(args.num_omp_threads))
      )
      # TODO(haibin) make these runtime options
      m = 512
      k = [50000, 100000]
      n = [64, 128]
      density = [
          1.00,
          0.90,
          0.70,
          0.50,
          0.30,
          0.20,
          0.10,
          0.07,
          0.05,
          0.02,
          0.01,
          0.005,
          0.001,
      ]
      num_repeat = 10
      # contexts = [mx.cpu(), mx.gpu(0)]
      contexts = [mx.cpu()]
      for i in range(2):
          for ctx in contexts:
              for den in density:
                  bench_dot_forward(m, k[i], n[i], den, ctx, num_repeat)
  
      print("dot_backward\tdot(csr.T, dns)")
      print(
          "density(%)\tcontext\tn\tm\tk\tt_dense/t_sparse\tt_dense\tt_sparse"
          "\tt_scipy_dense/t_scipy_sparse\tt_scipy_dense\tt_scipy_sparse"
      )
      for i in range(2):
          for ctx in contexts:
              for den in density:
                  bench_dot_backward(
                      m, k[i], n[i], den, ctx, num_repeat
                  )
  
file_path: mxnet/benchmark/python/sparse/sparse_op.py
imports: from __future__ import print_function
  import ctypes
  from mxnet.test_utils import *
  import scipy.sparse
  import os
  import time
  import argparse
  from mxnet.base import check_call, _LIB
  from mxnet.test_utils import get_bz2_data
  from util import estimate_density
label_desc: Use image node_id 3 for calling a global function with example usage: test_dot_synthetic() and returns: unknown, unknown