<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/105701>105701</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [mlir] No support for creating DenseElementsAttr with ComplexType through the CAPI and Python APIs
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            mlir
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          christopherbate
      </td>
    </tr>
</table>

<pre>
    Basic info:

- `DenseElementsAttr` can have a ComplexType element type. Iterating over the elements can be done with `denseAttr.getValues<std::complex<(APFloat|APInt|pod type)>>`. If you iterate with `denseAttr.getValues<Attribute>`, then you the Attribute returned is an `ArrayAttr` containing the individual real/complex elements.

- `DenseElementsAttr` of `ComplexType` element type is also a `DenseIntOrFPElementsAttr`.

Currently in the Python API you cannot even do `attr = ir.Attribute.parse("dense<(0.1, 0.2)> : tensor<128xcomplex<f32>>` because the [default attribute casters registered against `DenseIntOrFPElementsAttr` attempt to immediately cast any created Attribute into a more refined type](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Bindings/Python/IRAttributes.cpp#L1399). Therefore that Python line will raise an exception with message `Can't cast unknown element type DenseIntOrFPElementsAttr`.

There doesn't appear to be any other workaround to create such an attribute through the Python API, making it impossible without tweaking the C++ code. 

I took a stab at creating the required CAPIs. It requires a choice on how to specify the complex numbers. For splat `DenseElementsAttr`, it's simple enough to add APIs that create the splat constant by passing individual `(float|double) re, (float|double) im` components. For non-splat constants, I think you would just pass `const float*` containing interleaved real/imag components and copying to a `std::vector<std::complex<float>>` for handoff to the `DenseElementsAttr` builder. I don't think there's a portable way to avoid creating the intermediate vector of `std::complex`. 
 

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVk1v2zgQ_TX0ZVBBpvx58MFxasDAYjdYFHsfiWOLDUVqyZFT__vFUI7jpC3aBYLIEMWZN2_ePBJTsidPtFHzBzV_nODAbYibpo02cehbijUyTepgLpsHTLYB649BVVtVPqry-v8TqEX5SD7RZ0cdeU5b5qgWJTToocUzAcIudL2jb18uPQGNnwFfeirgwBSRrT9BOFMEbm8fpBygJjDBE7xYbiWTkUySoTgR_4NuoKSqXWIjsKptMyZS1U7p1fZp7wKyWu62Twcvzz6YnFfptao-y9-iLOBwhEsYwGYov0olL2w9MI27ld4JaJ8jCPrbOkTiIXoyYBOgl4jbGPFyoyd4RuuldNlnvbFnawZ0EAmd0vtrLTc-it-jPRxl6Y5xeXlPesbjUgC8xTh4_ivunz6EepdwN8RInt0FrM-Any7cBg_bp0OuvUHvAwOdyYMJEhmZI6jqEWwsbqwUPcZESq-U1pngsVVlMRUmy0KPrQFVbYHJpxBVtZvq1be3zh4rfWse1NTgkCgjUvMHQ0ccHAPeutBgYooJIp2s_CIDeELrE_-ieolBXc_AAWzXkbHI5C45IKC_QBMJmcxdx61nYbULUbp_tNL8LLf5o9KrlrlPIlO9V3p_stwOddGETum9c-fXx6c-hq_UsNL72oVa6X2H1svD2SjfWHn3IHLxp6T0fuyD0vvD3zckqWj6Xunqj2m1Xiu9LuBLS5GOAoxb5NfmOZtHyzmIaBOJTOlbQz3b4Mc56CglPFGWFHqllzwSMPhnH178e2H9rpYyGDCB0hgR-54wCtE1ZWoDtxThJcRnjGHwRpZGuiENTSs43zrMbQzDqf0gSpFTh88yXpbBdn1IydZuHO8wMPALjcuyb6f0g9IP0ARDBdxjPQCH8AwIibEG5BHH675I_w5WNCUWk8TOXl8lQGjaYBuC4KENL1JD6qmxx0ve-jrefuhqiqmAfYiQeof8s9GWkiwrvUyQrGwG8mPlAdAYqTqN7b1yJWnGiE3widEz1BfoxfeFljfHycFXx6tbmjDUTjwSIknOHy7ZbjSxrg8-u1PG74P_9D5jkggH4Nb652wUL2FwBr4OiTMSyZ2_hTGH3n4wR-uZoiM8k3l1Rtvh6S41oDfQhP6Su3L1tduRcKaGs4v84JAYU97M5BgitOhNOB4lTvaUn7hsPVhnKBZwkPMpq3gsUZRLuUcIfYiMWXN4ycDOwZr3AsrVXc0FRqhXB_8OrhxVoyavj4nZVGZdrXFCm-lSz6rZYjWtJu1mhXpJ08V8ulhMdTUvkebVtFqsaY5UmnI2sRtd6lm50nq6nFaVLpr1saFFVeKsJL2ar9SspA6tK8SSihBPE5vSQJtpOV-W04nDmlzK9watR2PScoOIm2xh9XBKalY6mzi9RWDLLt818ob5I_wZIA29kJSZv_HyHeGjFd1fIu5nXkYvS-Bt-NNkiG7zvw031yieei3zvNH_BQAA__8rFRJX">