diff --git a/dask/array/random.py b/dask/array/random.py
index 71050b304..9a1b0b364 100644
--- a/dask/array/random.py
+++ b/dask/array/random.py
@@ -44,8 +44,13 @@ class RandomState(object):
         self._numpy_state.seed(seed)
 
     def _wrap(self, func, *args, **kwargs):
+        """ Wrap numpy random function to produce dask.array random function
+
+        extra_chunks should be a chunks tuple to append to the end of chunks
+        """
         size = kwargs.pop('size')
         chunks = kwargs.pop('chunks')
+        extra_chunks = kwargs.pop('extra_chunks', ())
 
         if not isinstance(size, (tuple, list)):
             size = (size,)
@@ -62,12 +67,13 @@ class RandomState(object):
         seeds = different_seeds(len(sizes), self._numpy_state)
         token = tokenize(seeds, size, chunks, args, kwargs)
         name = 'da.random.{0}-{1}'.format(func.__name__, token)
-        keys = product([name], *[range(len(bd)) for bd in chunks])
+        keys = product([name], *([range(len(bd)) for bd in chunks]
+                               + [[0]] * len(extra_chunks)))
         vals = ((_apply_random, func.__name__, seed, size, args, kwargs)
                 for seed, size in zip(seeds, sizes))
         dsk = dict(zip(keys, vals))
 
-        return Array(dsk, name, chunks, dtype=dtype)
+        return Array(dsk, name, chunks + extra_chunks, dtype=dtype)
 
     @doc_wraps(np.random.RandomState.beta)
     def beta(self, a, b, size=None, chunks=None):
@@ -144,7 +150,11 @@ class RandomState(object):
         return self._wrap(np.random.RandomState.logseries, p,
                          size=size, chunks=chunks)
 
-    # multinomial
+    @doc_wraps(np.random.RandomState.multinomial)
+    def multinomial(self, n, pvals, size=None, chunks=None):
+        return self._wrap(np.random.RandomState.multinomial, n, pvals,
+                          size=size, chunks=chunks,
+                          extra_chunks=((len(pvals),),))
 
     @doc_wraps(np.random.RandomState.negative_binomial)
     def negative_binomial(self, n, p, size=None, chunks=None):
@@ -295,6 +305,7 @@ laplace = _state.laplace
 logistic = _state.logistic
 lognormal = _state.lognormal
 logseries = _state.logseries
+multinomial = _state.multinomial
 negative_binomial = _state.negative_binomial
 noncentral_chisquare = _state.noncentral_chisquare
 noncentral_f = _state.noncentral_f

Multinomial random generator
`dask/array/random.py` is missing a multinomial random generator (there is aplaceholder `# multinomial`).

Will dask have a multinomial random generator at some point? Does it require a significantly different approach than the other generators?
diff --git a/dask/array/tests/test_random.py b/dask/array/tests/test_random.py
index 855b200fd..1112a13ae 100644
--- a/dask/array/tests/test_random.py
+++ b/dask/array/tests/test_random.py
@@ -134,6 +134,7 @@ def test_random_all():
     da.random.logistic(size=5, chunks=3).compute()
     da.random.lognormal(size=5, chunks=3).compute()
     da.random.logseries(0.5, size=5, chunks=3).compute()
+    da.random.multinomial(20, [1/6.]*6, size=5, chunks=3).compute()
     da.random.negative_binomial(5, 0.5, size=5, chunks=3).compute()
     da.random.noncentral_chisquare(2, 2, size=5, chunks=3).compute()
 
@@ -159,3 +160,11 @@ def test_random_all():
     da.random.standard_gamma(2, size=5, chunks=3).compute()
     da.random.standard_normal(size=5, chunks=3).compute()
     da.random.standard_t(2, size=5, chunks=3).compute()
+
+
+def test_multinomial():
+    for size, chunks in [(5, 3), ((5, 4), (2, 3))]:
+        x = da.random.multinomial(20, [1/6.]*6, size=size, chunks=chunks)
+        y = np.random.multinomial(20, [1/6.]*6, size=size)
+
+        assert x.shape == y.shape == x.compute().shape

pip install -e .[complete]
parse_log_pytest
numpy>=1.16.0 pandas>=1.0.0 cloudpickle partd distributed s3fs toolz psutil pytables bokeh bcolz scipy h5py ipython
pytest
apt-get update apt-get install -y graphviz liblzma-dev
3.5
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aiobotocore @ file:///opt/conda/conda-bld/aiobotocore_1643638228694/work
aiohttp @ file:///tmp/build/80754af9/aiohttp_1632748060317/work
aioitertools @ file:///tmp/build/80754af9/aioitertools_1607109665762/work
async-timeout==3.0.1
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
backcall @ file:///home/ktietz/src/ci/backcall_1611930011877/work
bcolz==1.2.1
bokeh @ file:///tmp/build/80754af9/bokeh_1620710048147/work
boto3==1.23.10
botocore==1.26.10
brotlipy==0.7.0
certifi==2021.5.30
cffi @ file:///tmp/build/80754af9/cffi_1625814693874/work
chardet @ file:///tmp/build/80754af9/chardet_1607706739153/work
click==8.0.3
cloudpickle @ file:///tmp/build/80754af9/cloudpickle_1632508026186/work
contextvars==2.4
cryptography @ file:///tmp/build/80754af9/cryptography_1635366128178/work
cytoolz==0.11.0
-e git+https://github.com/dask/dask.git@71e3e413d6e00942de3ff32a3ba378408f2648e9#egg=dask
decorator @ file:///opt/conda/conda-bld/decorator_1643638310831/work
distributed==1.9.5
fsspec @ file:///opt/conda/conda-bld/fsspec_1642510437511/work
h5py==2.10.0
HeapDict @ file:///Users/ktietz/demo/mc3/conda-bld/heapdict_1630598515714/work
idna @ file:///tmp/build/80754af9/idna_1637925883363/work
idna-ssl @ file:///tmp/build/80754af9/idna_ssl_1611752490495/work
immutables @ file:///tmp/build/80754af9/immutables_1628888996840/work
importlib-metadata==4.8.3
iniconfig==1.1.1
ipython @ file:///tmp/build/80754af9/ipython_1593447367857/work
ipython-genutils @ file:///tmp/build/80754af9/ipython_genutils_1606773439826/work
jedi @ file:///tmp/build/80754af9/jedi_1606932572482/work
Jinja2 @ file:///opt/conda/conda-bld/jinja2_1647436528585/work
jmespath @ file:///Users/ktietz/demo/mc3/conda-bld/jmespath_1630583964805/work
locket==0.2.1
MarkupSafe @ file:///tmp/build/80754af9/markupsafe_1621528150516/work
mock @ file:///tmp/build/80754af9/mock_1607622725907/work
msgpack @ file:///tmp/build/80754af9/msgpack-python_1612287171716/work
msgpack-python==0.5.6
multidict @ file:///tmp/build/80754af9/multidict_1607367768400/work
numexpr @ file:///tmp/build/80754af9/numexpr_1618853194344/work
numpy @ file:///tmp/build/80754af9/numpy_and_numpy_base_1603483703303/work
olefile @ file:///Users/ktietz/demo/mc3/conda-bld/olefile_1629805411829/work
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
pandas==1.1.5
parso==0.7.0
partd @ file:///opt/conda/conda-bld/partd_1647245470509/work
pexpect @ file:///tmp/build/80754af9/pexpect_1605563209008/work
pickleshare @ file:///tmp/build/80754af9/pickleshare_1606932040724/work
Pillow @ file:///tmp/build/80754af9/pillow_1625670622947/work
pluggy==1.0.0
prompt-toolkit @ file:///tmp/build/80754af9/prompt-toolkit_1633440160888/work
psutil @ file:///tmp/build/80754af9/psutil_1612297621795/work
ptyprocess @ file:///tmp/build/80754af9/ptyprocess_1609355006118/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl
py==1.11.0
pycparser @ file:///tmp/build/80754af9/pycparser_1636541352034/work
Pygments @ file:///opt/conda/conda-bld/pygments_1644249106324/work
pyOpenSSL @ file:///opt/conda/conda-bld/pyopenssl_1643788558760/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
PySocks @ file:///tmp/build/80754af9/pysocks_1605305763431/work
pytest==7.0.1
python-dateutil @ file:///tmp/build/80754af9/python-dateutil_1626374649649/work
pytz==2021.3
PyYAML==5.4.1
s3fs==0.4.2
s3transfer==0.5.2
scipy @ file:///tmp/build/80754af9/scipy_1597686635649/work
six @ file:///tmp/build/80754af9/six_1644875935023/work
sortedcontainers @ file:///tmp/build/80754af9/sortedcontainers_1623949099177/work
tables==3.6.1
tblib @ file:///Users/ktietz/demo/mc3/conda-bld/tblib_1629402031467/work
tomli==1.2.3
toolz @ file:///tmp/build/80754af9/toolz_1636545406491/work
tornado @ file:///tmp/build/80754af9/tornado_1606942266872/work
traitlets @ file:///tmp/build/80754af9/traitlets_1632746497744/work
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
urllib3 @ file:///opt/conda/conda-bld/urllib3_1643638302206/work
wcwidth @ file:///Users/ktietz/demo/mc3/conda-bld/wcwidth_1629357192024/work
wrapt==1.12.1
yarl @ file:///tmp/build/80754af9/yarl_1606939915466/work
zict==2.0.0
zipp==3.6.0

name: dask
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - aiobotocore=2.1.0=pyhd3eb1b0_0
  - aiohttp=3.7.4.post0=py36h7f8727e_2
  - aioitertools=0.7.1=pyhd3eb1b0_0
  - async-timeout=3.0.1=py36h06a4308_0
  - attrs=21.4.0=pyhd3eb1b0_0
  - backcall=0.2.0=pyhd3eb1b0_0
  - bcolz=1.2.1=py36h04863e7_0
  - blas=1.0=openblas
  - blosc=1.21.3=h6a678d5_0
  - bokeh=2.3.2=py36h06a4308_0
  - brotlipy=0.7.0=py36h27cfd23_1003
  - bzip2=1.0.8=h5eee18b_6
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - cffi=1.14.6=py36h400218f_0
  - chardet=4.0.0=py36h06a4308_1003
  - click=8.0.3=pyhd3eb1b0_0
  - cloudpickle=2.0.0=pyhd3eb1b0_0
  - contextvars=2.4=py_0
  - cryptography=35.0.0=py36hd23ed53_0
  - cytoolz=0.11.0=py36h7b6447c_0
  - decorator=5.1.1=pyhd3eb1b0_0
  - freetype=2.12.1=h4a9f257_0
  - fsspec=2022.1.0=pyhd3eb1b0_0
  - giflib=5.2.2=h5eee18b_0
  - h5py=2.10.0=py36h7918eee_0
  - hdf5=1.10.4=hb1b8bf9_0
  - heapdict=1.0.1=pyhd3eb1b0_0
  - idna=3.3=pyhd3eb1b0_0
  - idna_ssl=1.1.0=py36h06a4308_0
  - immutables=0.16=py36h7f8727e_0
  - ipython=7.16.1=py36h5ca1d4c_0
  - ipython_genutils=0.2.0=pyhd3eb1b0_1
  - jedi=0.17.2=py36h06a4308_1
  - jinja2=3.0.3=pyhd3eb1b0_0
  - jmespath=0.10.0=pyhd3eb1b0_0
  - jpeg=9e=h5eee18b_3
  - lcms2=2.16=hb9589c4_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - lerc=4.0.0=h6a678d5_0
  - libdeflate=1.22=h5eee18b_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgfortran-ng=7.5.0=ha8ba4b0_17
  - libgfortran4=7.5.0=ha8ba4b0_17
  - libgomp=11.2.0=h1234567_1
  - libopenblas=0.3.18=hf726d26_0
  - libpng=1.6.39=h5eee18b_0
  - libstdcxx-ng=11.2.0=h1234567_1
  - libtiff=4.5.1=hffd6297_1
  - libwebp=1.2.4=h11a3e52_1
  - libwebp-base=1.2.4=h5eee18b_1
  - locket=0.2.1=py36h06a4308_1
  - lz4-c=1.9.4=h6a678d5_1
  - lzo=2.10=h7b6447c_2
  - markupsafe=2.0.1=py36h27cfd23_0
  - mock=4.0.3=pyhd3eb1b0_0
  - multidict=5.1.0=py36h27cfd23_2
  - ncurses=6.4=h6a678d5_0
  - numexpr=2.7.3=py36h4be448d_1
  - numpy=1.19.2=py36h6163131_0
  - numpy-base=1.19.2=py36h75fe3a5_0
  - olefile=0.46=pyhd3eb1b0_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pandas=1.1.5=py36ha9443f7_0
  - parso=0.7.0=py_0
  - partd=1.2.0=pyhd3eb1b0_1
  - pexpect=4.8.0=pyhd3eb1b0_3
  - pickleshare=0.7.5=pyhd3eb1b0_1003
  - pillow=8.3.1=py36h5aabda8_0
  - pip=21.2.2=py36h06a4308_0
  - prompt-toolkit=3.0.20=pyhd3eb1b0_0
  - psutil=5.8.0=py36h27cfd23_1
  - ptyprocess=0.7.0=pyhd3eb1b0_2
  - pycparser=2.21=pyhd3eb1b0_0
  - pygments=2.11.2=pyhd3eb1b0_0
  - pyopenssl=22.0.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pysocks=1.7.1=py36h06a4308_0
  - pytables=3.6.1=py36h71ec239_0
  - python=3.6.13=h12debd9_1
  - python-dateutil=2.8.2=pyhd3eb1b0_0
  - pytz=2021.3=pyhd3eb1b0_0
  - pyyaml=5.4.1=py36h27cfd23_1
  - readline=8.2=h5eee18b_0
  - scipy=1.5.2=py36habc2bb6_0
  - setuptools=58.0.4=py36h06a4308_0
  - six=1.16.0=pyhd3eb1b0_1
  - sortedcontainers=2.4.0=pyhd3eb1b0_0
  - sqlite=3.45.3=h5eee18b_0
  - tblib=1.7.0=pyhd3eb1b0_0
  - tk=8.6.14=h39e8969_0
  - toolz=0.11.2=pyhd3eb1b0_0
  - tornado=6.1=py36h27cfd23_0
  - traitlets=4.3.3=py36h06a4308_0
  - typing-extensions=4.1.1=hd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - urllib3=1.26.8=pyhd3eb1b0_0
  - wcwidth=0.2.5=pyhd3eb1b0_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - wrapt=1.12.1=py36h7b6447c_1
  - xz=5.6.4=h5eee18b_1
  - yaml=0.2.5=h7b6447c_0
  - yarl=1.6.3=py36h27cfd23_0
  - zict=2.0.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - zstd=1.5.6=hc292b87_0
  - pip:
      - boto3==1.23.10
      - botocore==1.26.10
      - distributed==1.9.5
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - msgpack-python==0.5.6
      - pluggy==1.0.0
      - py==1.11.0
      - pytest==7.0.1
      - s3fs==0.4.2
      - s3transfer==0.5.2
      - tomli==1.2.3
      - zipp==3.6.0
prefix: /opt/conda/envs/dask

dask/array/tests/test_random.py::test_random_all dask/array/tests/test_random.py::test_multinomial
dask/array/tests/test_random.py::test_RandomState dask/array/tests/test_random.py::test_concurrency dask/array/tests/test_random.py::test_doc_randomstate dask/array/tests/test_random.py::test_serializability dask/array/tests/test_random.py::test_determinisim_through_dask_values dask/array/tests/test_random.py::test_randomstate_consistent_names dask/array/tests/test_random.py::test_random dask/array/tests/test_random.py::test_parametrized_random_function dask/array/tests/test_random.py::test_kwargs dask/array/tests/test_random.py::test_unique_names dask/array/tests/test_random.py::test_docs dask/array/tests/test_random.py::test_can_make_really_big_random_array dask/array/tests/test_random.py::test_random_seed
dask/array/random.py
dask/array/random.py