问:
How to write the data as XML Tree into a file using Oracle dbms_xslprocessor
Oracle Version

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

The existing code in production uses the DBMS_XMLDOM.WRITETOFILE as below and we have a performance issue.

```<code>DECLARE
  vFileName         VARCHAR2(100) := 'domdata.xml';
  vDir              VARCHAR2(100) := 'STATEMENTSXML';
  vAllDataXML       XMLTYPE;
  XMLBillData       XMLTYPE;
  vXMLFileContents  CLOB;
  vXMLDoc                     XMLDOM.DOMDocument;
BEGIN
    begin
    utl_file.fremove(vDir,vFileName);
    exception
      when others then null;
    end;
        SELECT XMLCONCAT(
                (SELECT XMLAGG(XMLELEMENT("GLOBALMESSAGES", XMLFOREST
                    (
                        ub.object_type, count(ub.object_name) object_cnt
                    )))
                 FROM user_objects ub
                WHERE object_type IN ('TABLE','VIEW')
                GROUP BY object_type
                 ))
        INTO XMLBillData
        FROM dual;
    vXMLFileContents := '<Data>' || XMLBillData.getclobval() || '</Data>';
    vAllDataXML := XMLTYPE(vXMLFileContents);
    vXMLDoc := DBMS_XMLDOM.NEWDOMDOCUMENT(vAllDataXML);
    DBMS_XMLDOM.WRITETOFILE(vXMLDoc, vDir||'\'||vFileName, 'US-ASCII');
END;

***OutPut -***
<?xml version="1.0" encoding="US-ASCII"?>
<Data>
  <GLOBALMESSAGES>
    <OBJECT_TYPE>TABLE</OBJECT_TYPE>
    <OBJECT_CNT>54</OBJECT_CNT>
  </GLOBALMESSAGES>
  <GLOBALMESSAGES>
    <OBJECT_TYPE>VIEW</OBJECT_TYPE>
    <OBJECT_CNT>1242</OBJECT_CNT>
  </GLOBALMESSAGES>
</Data>
</code>```

To fix the performance issue we are planning to use the below code using dbms_xslprocessor.clob2file.

```<code>DECLARE
  vFileName         VARCHAR2(100) := 'xlsdata.xml';
  vDir              VARCHAR2(100) := 'STATEMENTSXML';
  vAllDataXML       XMLTYPE;
  XMLBillData       XMLTYPE;
  vXMLFileContents  CLOB;
  vXMLDoc                     XMLDOM.DOMDocument;
BEGIN
    begin
    utl_file.fremove(vDir,vFileName);
    exception
      when others then null;
    end;
         SELECT XMLCONCAT(
                (SELECT XMLAGG(XMLELEMENT("GLOBALMESSAGES", XMLFOREST
                    (
                        ub.object_type, count(ub.object_name) object_cnt
                    )))
                 FROM user_objects ub
                WHERE object_type IN ('TABLE','VIEW')
                GROUP BY object_type
                 ))
        INTO XMLBillData
        FROM dual;
   vXMLFileContents := '<Data>' || XMLBillData.getclobval() || '</Data>';
    --vAllDataXML := XMLTYPE(vXMLFileContents);
--  vXMLDoc := DBMS_XMLDOM.NEWDOMDOCUMENT(vAllDataXML);
--  DBMS_XMLDOM.WRITETOFILE(vXMLDoc, vDir||'\'||vFileName, 'US-ASCII');
    dbms_xslprocessor.clob2file(vXMLFileContents, vDir, vFileName,1);
END;

***OutPut -***
<Data><GLOBALMESSAGES><OBJECT_TYPE>TABLE</OBJECT_TYPE><OBJECT_CNT>54</OBJECT_CNT></GLOBALMESSAGES><GLOBALMESSAGES><OBJECT_TYPE>VIEW</OBJECT_TYPE><OBJECT_CNT>1242</OBJECT_CNT></GLOBALMESSAGES></Data>
</code>```

My research on google says that writetofile is slower as it writes the file contents as XML Tree but clob2file writes as a long string. Also If you observe the outputs, the header line with encoding is missing with the clob2file.

Is there way I can match the output returned by writetofile with clob2file? Am I missing something here?

Also After the above process, I have the next step to validate the generated file. The validate process copies the file to another directory and search for spaces.
The UTL_FILE.FCOPY throwing ORA-29284: file read error. I believe this is due to permissions after creating the new file using clob2file but not with writetofile. Is this true? If so what is the solution for this?

Thanks In Advance
VB

Body:
Oracle Version

Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

The existing code in production uses the DBMS_XMLDOM.WRITETOFILE as below and we have a performance issue.

DECLARE
  vFileName         VARCHAR2(100) := 'domdata.xml';
  vDir              VARCHAR2(100) := 'STATEMENTSXML';
  vAllDataXML       XMLTYPE;
  XMLBillData       XMLTYPE;
  vXMLFileContents  CLOB;
  vXMLDoc                     XMLDOM.DOMDocument;
BEGIN
    begin
    utl_file.fremove(vDir,vFileName);
    exception
      when others then null;
    end;
        SELECT XMLCONCAT(
                (SELECT XMLAGG(XMLELEMENT("GLOBALMESSAGES", XMLFOREST
                    (
                        ub.object_type, count(ub.object_name) object_cnt
                    )))
                 FROM user_objects ub
                WHERE object_type IN ('TABLE','VIEW')
                GROUP BY object_type
                 ))
        INTO XMLBillData
        FROM dual;
    vXMLFileContents := '<Data>' || XMLBillData.getclobval() || '</Data>';
    vAllDataXML := XMLTYPE(vXMLFileContents);
    vXMLDoc := DBMS_XMLDOM.NEWDOMDOCUMENT(vAllDataXML);
    DBMS_XMLDOM.WRITETOFILE(vXMLDoc, vDir||'\'||vFileName, 'US-ASCII');
END;

***OutPut -***
<?xml version="1.0" encoding="US-ASCII"?>
<Data>
  <GLOBALMESSAGES>
    <OBJECT_TYPE>TABLE</OBJECT_TYPE>
    <OBJECT_CNT>54</OBJECT_CNT>
  </GLOBALMESSAGES>
  <GLOBALMESSAGES>
    <OBJECT_TYPE>VIEW</OBJECT_TYPE>
    <OBJECT_CNT>1242</OBJECT_CNT>
  </GLOBALMESSAGES>
</Data>

To fix the performance issue we are planning to use the below code using dbms_xslprocessor.clob2file.

DECLARE
  vFileName         VARCHAR2(100) := 'xlsdata.xml';
  vDir              VARCHAR2(100) := 'STATEMENTSXML';
  vAllDataXML       XMLTYPE;
  XMLBillData       XMLTYPE;
  vXMLFileContents  CLOB;
  vXMLDoc                     XMLDOM.DOMDocument;
BEGIN
    begin
    utl_file.fremove(vDir,vFileName);
    exception
      when others then null;
    end;
         SELECT XMLCONCAT(
                (SELECT XMLAGG(XMLELEMENT("GLOBALMESSAGES", XMLFOREST
                    (
                        ub.object_type, count(ub.object_name) object_cnt
                    )))
                 FROM user_objects ub
                WHERE object_type IN ('TABLE','VIEW')
                GROUP BY object_type
                 ))
        INTO XMLBillData
        FROM dual;
   vXMLFileContents := '<Data>' || XMLBillData.getclobval() || '</Data>';
    --vAllDataXML := XMLTYPE(vXMLFileContents);
--  vXMLDoc := DBMS_XMLDOM.NEWDOMDOCUMENT(vAllDataXML);
--  DBMS_XMLDOM.WRITETOFILE(vXMLDoc, vDir||'\'||vFileName, 'US-ASCII');
    dbms_xslprocessor.clob2file(vXMLFileContents, vDir, vFileName,1);
END;

***OutPut -***
<Data><GLOBALMESSAGES><OBJECT_TYPE>TABLE</OBJECT_TYPE><OBJECT_CNT>54</OBJECT_CNT></GLOBALMESSAGES><GLOBALMESSAGES><OBJECT_TYPE>VIEW</OBJECT_TYPE><OBJECT_CNT>1242</OBJECT_CNT></GLOBALMESSAGES></Data>

My research on google says that writetofile is slower as it writes the file contents as XML Tree but clob2file writes as a long string. Also If you observe the outputs, the header line with encoding is missing with the clob2file.

Is there way I can match the output returned by writetofile with clob2file? Am I missing something here?

Also After the above process, I have the next step to validate the generated file. The validate process copies the file to another directory and search for spaces.
The UTL_FILE.FCOPY throwing ORA-29284: file read error. I believe this is due to permissions after creating the new file using clob2file but not with writetofile. Is this true? If so what is the solution for this?

Thanks In Advance
VB


来源: stackexchange

问:
How to paginate data from api?
I'm working on a project using react (next.js) and I can get data from Api perfectly, but for some reasons (performance and ...) the Api doesn't return the whole data and I should get one slice of the data time to time until the Api method returns empty array([]). my Api function is this:

getBlogList(count,skip)

count is the count of returned blogs and skip is count of skipped blogs.

I have show more button to show more blogs when the user click it.

The show more buttons works good. But I want the page to be shown after refresh just like it did at the first render. But when I refresh the page I see it messy. for example some times I didn't see any blog title or I see only the last one! when I logged the skip state in showMoreBlogs function, it was not 0. Although I set it to zero in the useEffect() and it was  expected to be 0 after refresh!

This is my code :

```<code>const count=3
  const [blogs,setBlogs]:any[]=useState([])
 var [skip,setSkip]=useState(0);

const getBlogs=()=>{
   await getBlogList(count,skip).then(async(response:any)=>{
        console.log(response)

        setBlogs(response.data)
        setSkip(skip+count)

       }).catch((er)=>{console.log(er); return []})
}

 useEffect(()=>{
      setSkip(0)

      getBlogs();

      },[])

//wehn you click on the show more button
const showMoreBlogs=()=>{
 console.log(skip)
 await getBlogList(count,skip).then(async(response:any)=>{
          console.log(response.data)

         if(response.data.length>0){
          setBlogs([...blogs,...response.data])
          console.log(response.data)
          setSkip(skip+count)
          console.log(skip+count)

         }
}
}

return(<>

{blogs.map((el)=>{
return <span>{el.title}</span>
})}
   <button className={` hover-up-5 top-0 relative inline-block py-4 duration-500 px-8 text-xs text-white font-semibold leading-none bg-color-400 hover:bg-color-500 rounded`}
       onClick={(e)=>{e.preventDefault();showMoreBlogs();}}
       >Show more</button>

</>)

</code>```

It turned out that the skip state saves the previous value after the refresh! What should I do to refresh skip state after refreshing the page?

ContentLicense: CC BY-SA 4.0

Title: How to paginate data from api?

Body:
I'm working on a project using react (next.js) and I can get data from Api perfectly, but for some reasons (performance and ...) the Api doesn't return the whole data and I should get one slice of the data time to time until the Api method returns empty array([]). my Api function is this:

getBlogList(count,skip)

count is the count of returned blogs and skip is count of skipped blogs.

I have show more button to show more blogs when the user click it.

The show more buttons works good. But I want the page to be shown after refresh just like it did at the first render. But when I refresh the page I see it messy. for example some times I didn't see any blog title or I see only the last one! when I logged the skip state in showMoreBlogs function, it was not 0. Although I set it to zero in the useEffect() and it was  expected to be 0 after refresh!

This is my code :

const count=3
  const [blogs,setBlogs]:any[]=useState([])
 var [skip,setSkip]=useState(0);

const getBlogs=()=>{
   await getBlogList(count,skip).then(async(response:any)=>{
        console.log(response)

        setBlogs(response.data)
        setSkip(skip+count)

       }).catch((er)=>{console.log(er); return []})
}

 useEffect(()=>{
      setSkip(0)

      getBlogs();

      },[])

//wehn you click on the show more button
const showMoreBlogs=()=>{
 console.log(skip)
 await getBlogList(count,skip).then(async(response:any)=>{
          console.log(response.data)

         if(response.data.length>0){
          setBlogs([...blogs,...response.data])
          console.log(response.data)
          setSkip(skip+count)
          console.log(skip+count)

         }
}
}

return(<>

{blogs.map((el)=>{
return {el.title}
})}
   <button className={` hover-up-5 top-0 relative inline-block py-4 duration-500 px-8 text-xs text-white font-semibold leading-none bg-color-400 hover:bg-color-500 rounded`}
       onClick={(e)=>{e.preventDefault();showMoreBlogs();}}
       >Show more</button>

</>)

It turned out that the skip state saves the previous value after the refresh! What should I do to refresh skip state after refreshing the page?


问:
anchoredPosition clamp delay
Good afternoon everyone, I have a super simple OnDrag method, it works great, even if the sprite and "remains" of the cursor, after a moment it catches up with it

```<code>public void OnDrag(PointerEventData eventData)
    {

        arc = rectTransform.anchoredPosition + eventData.delta / canvas.scaleFactor;
        rectTransform.anchoredPosition = arc;
</code>```

enter image description here

However, when I try to add a border to a UI element using Clamp, the cursor stops "catching up" with the UI element, and the further it goes, the more it stays. Could you please suggest me a solution to fix this. Thank you in advance.

```<code>arc = rectTransform.anchoredPosition + eventData.delta / canvas.scaleFactor;
arc.x = Mathf.Clamp(arc.x, -500f, 500f);
arc.y = Mathf.Clamp(arc.y, -500f, 500f);
rectTransform.anchoredPosition = arc;
</code>```

enter image description here

Turn Off Vsync helps a little bit.I understand that the whole thing is in calculations that do not keep up with the update of frames or something like that.

Title: anchoredPosition clamp delay

Body:
Good afternoon everyone, I have a super simple OnDrag method, it works great, even if the sprite and "remains" of the cursor, after a moment it catches up with it

public void OnDrag(PointerEventData eventData)
    {

        arc = rectTransform.anchoredPosition + eventData.delta / canvas.scaleFactor;
        rectTransform.anchoredPosition = arc;

enter image description here

However, when I try to add a border to a UI element using Clamp, the cursor stops "catching up" with the UI element, and the further it goes, the more it stays. Could you please suggest me a solution to fix this. Thank you in advance.

arc = rectTransform.anchoredPosition + eventData.delta / canvas.scaleFactor;
arc.x = Mathf.Clamp(arc.x, -500f, 500f);
arc.y = Mathf.Clamp(arc.y, -500f, 500f);
rectTransform.anchoredPosition = arc;

enter image description here

Turn Off Vsync helps a little bit.I understand that the whole thing is in calculations that do not keep up with the update of frames or something like that.


问:
Servlet mapping for specific URL not working in Jersey 2
I am trying to use Jersey 2.x and have a servlet call "myapp", configuration on web.xml is as follows:

<servlet>
    <servlet-name>myapp</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
            com.private.myapp.resource
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
```
<p>and have a servlet mapping as follows</p>
<pre class="lang-xml prettyprint-override"><code><servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/instance/create</url-pattern>
    <url-pattern>/instance/list</url-pattern>
</servlet-mapping>
</code>```

when I request to $SERVER_ROOT/instance/create or $SERVER_ROOT/instance/list its return 404
but when I change servlet mapping as follows

<servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
```

then requesting to $SERVER_ROOT/instance/create or $SERVER_ROOT/instance/list response as expected
can anyone tell what I am missing?

Body:
I am trying to use Jersey 2.x and have a servlet call "myapp", configuration on web.xml is as follows:

<servlet>
    <servlet-name>myapp</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
            com.private.myapp.resource
        </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

and have a servlet mapping as follows

<servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/instance/create</url-pattern>
    <url-pattern>/instance/list</url-pattern>
</servlet-mapping>

when I request to $SERVER_ROOT/instance/create or $SERVER_ROOT/instance/list its return 404
but when I change servlet mapping as follows

<servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

then requesting to $SERVER_ROOT/instance/create or $SERVER_ROOT/instance/list response as expected
can anyone tell what I am missing?


问:
Alert Dialog does not show when I try to pass useDisclosure variables to a child component function in Nextjs and Chakra
When this runs, and I click on the button, the alert dialogue does not get displayed, so I was wondering how to fix this issue?

This is my simplified version of the parent code:

```<code>const {
    isOpen: isOpen3,
    onOpen: onOpen3,
    onClose: onClose3,
  } = useDisclosure();
StartupComponent(
     accessories[res.get("selectedAccessory")][1],
     lvl,
     startupName,
     String(document),
     isOpen3,
     onOpen3,
     onClose3,
     cancelRef
)
</code>```

While this is my child component code.

The button when clicked though does not display the alert dialogue...

Thank you in advance for your help!

```<code>const StartupComponent = (
  img,
  level,
  name,
  id,
  isOpen,
  onOpen,
  onClose,
  cancelRef
) => {

  return (
    <Flex
      direction={"row"}
      alignItems={"center"}
      justifyContent={"center"}
      backgroundColor={"#303030"}
      width={"90%"}
      paddingTop={5}
      paddingBottom={5}
      paddingLeft={5}
      borderRadius={3}
      boxShadow={"0 5px 5px rgba(0, 0, 0, 0.5)"}
      _hover={{
        boxShadow: "0 5px 5px rgba(100,100,100,0.9)",
      }}
    >
      <AlertDialog
        isOpen={isOpen}
        leastDestructiveRef={cancelRef}
        onClose={onClose}
      >
        <AlertDialogOverlay>
          <AlertDialogContent>
            <AlertDialogHeader fontSize="lg" fontWeight="bold">
              Delete {name}
            </AlertDialogHeader>

            <AlertDialogBody>
              Are you sure you want to delete {name}? You can't undo this action
              afterwards.
            </AlertDialogBody>

            <AlertDialogFooter>
              <Button ref={cancelRef} onClick={onClose}>
                Cancel
              </Button>
              <Button
                colorScheme="red"
                onClick={() => {
                  deleteIt();
                  onClose();
                }}
                ml={3}
              >
                Stop Timer
              </Button>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialogOverlay>
      </AlertDialog>

      <Tooltip label={"Delete " + name + "..."} aria-label="A tooltip">
        <Button
          position={"absolute"}
          right={"28vw"}
          onClick={onOpen}
          colorScheme={"transparent"}
        >
          <Image
            src={"/assets/trash.png"}
            alt={"Gloppa menu"}
            width={35}
            height={35}
          />
        </Button>
      </Tooltip>
    </Flex>
  );
};
</code>```

Body:
When this runs, and I click on the button, the alert dialogue does not get displayed, so I was wondering how to fix this issue?

This is my simplified version of the parent code:

const {
    isOpen: isOpen3,
    onOpen: onOpen3,
    onClose: onClose3,
  } = useDisclosure();
StartupComponent(
     accessories[res.get("selectedAccessory")][1],
     lvl,
     startupName,
     String(document),
     isOpen3,
     onOpen3,
     onClose3,
     cancelRef
)

While this is my child component code.

The button when clicked though does not display the alert dialogue...

Thank you in advance for your help!

const StartupComponent = (
  img,
  level,
  name,
  id,
  isOpen,
  onOpen,
  onClose,
  cancelRef
) => {

  return (
    <Flex
      direction={"row"}
      alignItems={"center"}
      justifyContent={"center"}
      backgroundColor={"#303030"}
      width={"90%"}
      paddingTop={5}
      paddingBottom={5}
      paddingLeft={5}
      borderRadius={3}
      boxShadow={"0 5px 5px rgba(0, 0, 0, 0.5)"}
      _hover={{
        boxShadow: "0 5px 5px rgba(100,100,100,0.9)",
      }}
    >
      <AlertDialog
        isOpen={isOpen}
        leastDestructiveRef={cancelRef}
        onClose={onClose}
      >
        <AlertDialogOverlay>
          <AlertDialogContent>
            <AlertDialogHeader fontSize="lg" fontWeight="bold">
              Delete {name}
            </AlertDialogHeader>

            <AlertDialogBody>
              Are you sure you want to delete {name}? You can't undo this action
              afterwards.
            </AlertDialogBody>

            <AlertDialogFooter>
              <Button ref={cancelRef} onClick={onClose}>
                Cancel
              </Button>
              <Button
                colorScheme="red"
                onClick={() => {
                  deleteIt();
                  onClose();
                }}
                ml={3}
              >
                Stop Timer
              </Button>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialogOverlay>
      </AlertDialog>

      <Tooltip label={"Delete " + name + "..."} aria-label="A tooltip">
        <Button
          position={"absolute"}
          right={"28vw"}
          onClick={onOpen}
          colorScheme={"transparent"}
        >
          <Image
            src={"/assets/trash.png"}
            alt={"Gloppa menu"}
            width={35}
            height={35}
          />
        </Button>
      </Tooltip>
    </Flex>
  );
};


问:
Google Developer API: "The caller does not have permission" For a service account with Full Admin Access
I'm trying to setup automation for my App publication via google developer api. I have setup a service account as per the user guide with service account user + owner permissions. The service account shows up on the google play console and I've give it the full Admin access + full access on the app.

I've created the .json key for the service account as a small test, tried to use google-api-client library on python to see if it works. Note that I have only created a dummy app with a package name and haven't uploaded any APKs yet.

```<code>from google.oauth2 import service_account
import googleapiclient.discovery
import httplib2
if __name__ == '__main__':
    scopes = ['https://www.googleapis.com/auth/androidpublisher']
    package_name = 'xxxxxxxxxxxx'
    service_account_file = 'creds.json'
    credentials = service_account.Credentials.from_service_account_file(
        service_account_file, scopes=scopes)

    print(type(credentials))
    # delegated_cre.dentials = credentials.with_subject('rohella.anshuman@gmail.com')
    android = googleapiclient.discovery.build('androidpublisher', 'v3', credentials=credentials)
    res = android.edits().insert(body={}, packageName=package_name).execute()
    print(res)
</code>```

However, I keep getting the 403 permission denied error. I've checked all the access on api cloud/play console and it should work as per the official docs. Here is the log output

```<code>(env) ➜  android-publish python main.py
<class 'google.oauth2.service_account.Credentials'>
Traceback (most recent call last):
  File "/Users/xxxxxx/Workspace/xxxxxxxx/android-publish/main.py", line 14, in <module>
    res = android.edits().insert(body={}, packageName=package_name).execute()
  File "/Users/xxxxxxx/Workspace/xxxxxxxx/android-publish/env/lib/python3.9/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Users/xxxxxx/Workspace/xxxxx/android-publish/env/lib/python3.9/site-packages/googleapiclient/http.py", line 938, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.odecloud.odesocial.beta/edits?alt=json returned "The caller does not have permission". Details: "The caller does not have permission">
</code>```

Additional Info:

Permissions on google cloud console for the service account user.

Body:
I'm trying to setup automation for my App publication via google developer api. I have setup a service account as per the user guide with service account user + owner permissions. The service account shows up on the google play console and I've give it the full Admin access + full access on the app.

I've created the .json key for the service account as a small test, tried to use google-api-client library on python to see if it works. Note that I have only created a dummy app with a package name and haven't uploaded any APKs yet.

from google.oauth2 import service_account
import googleapiclient.discovery
import httplib2
if __name__ == '__main__':
    scopes = ['https://www.googleapis.com/auth/androidpublisher']
    package_name = 'xxxxxxxxxxxx'
    service_account_file = 'creds.json'
    credentials = service_account.Credentials.from_service_account_file(
        service_account_file, scopes=scopes)

    print(type(credentials))
    # delegated_cre.dentials = credentials.with_subject('rohella.anshuman@gmail.com')
    android = googleapiclient.discovery.build('androidpublisher', 'v3', credentials=credentials)
    res = android.edits().insert(body={}, packageName=package_name).execute()
    print(res)

However, I keep getting the 403 permission denied error. I've checked all the access on api cloud/play console and it should work as per the official docs. Here is the log output

(env) ➜  android-publish python main.py
<class 'google.oauth2.service_account.Credentials'>
Traceback (most recent call last):
  File "/Users/xxxxxx/Workspace/xxxxxxxx/android-publish/main.py", line 14, in <module>
    res = android.edits().insert(body={}, packageName=package_name).execute()
  File "/Users/xxxxxxx/Workspace/xxxxxxxx/android-publish/env/lib/python3.9/site-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/Users/xxxxxx/Workspace/xxxxx/android-publish/env/lib/python3.9/site-packages/googleapiclient/http.py", line 938, in execute
    raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.odecloud.odesocial.beta/edits?alt=json returned "The caller does not have permission". Details: "The caller does not have permission">

Additional Info:

Permissions on google cloud console for the service account user.


问:
RuntimeError: stack expects a non-empty TensorList
first of all I thank , I tried to train  model with  pytorch but I got the following error:
RuntimeError: stack expects a non-empty TensorList .I am trying to model a extract features point cloud using deep learning in pytorch.
I get the following error . Could anyone help on this? ************** ***************
Thanks!

```<code>def training_loop(gpu, training_dataloader, model, loss_fn, optimizer):
    losses = []
    correct = 0
    batch_results = dict()
    conf_mat = np.zeros((10,10))
    for batch_n, batch in enumerate(training_dataloader): #batch[batch, pos, ptr, y]
        batch_size = int(batch.batch.size()[0] / sample_points)

        if dimensionality == 3:
            # Input dim [:,3] for your geometry x,y,z
            X = batch.pos.cuda(non_blocking=True).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                dimensionality), fill_value=0.1)).cuda(gpu)
        else:
            # Input dim [:,6] for your geometry x,y,z and normals nx,ny,nz
            X = torch.cat((batch.pos.cuda(non_blocking=True), batch.normal.cuda(non_blocking=True)), 1).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                dimensionality), fill_value=0.1)).cuda(gpu)

        y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])

        # Compute predictions
        pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])

        if overall_classes_loss:
            # weighted CE Loss over all classes
            loss = loss_fn(pred, y)
        else:
            # weighted batchwise Loss
            sample_count = np.array([[x, batch.y.tolist().count(x)] for x in batch.y])[:,1]
            batch_weights = 1. / sample_count
            batch_weights = torch.from_numpy(batch_weights)
            batch_weights = batch_weights.double()
            loss = element_weighted_loss(pred, batch.y, batch_weights, gpu)

        correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        print(f"Loss: {loss}")

        tensor_list_y =  [torch.ones_like(y) for _ in range(dist.get_world_size())]
        tensor_list_pred = [torch.ones_like(y) for _ in range(dist.get_world_size())]
        torch.distributed.all_gather(tensor_list_y, y, group=None, async_op=False)
        torch.distributed.all_gather(tensor_list_pred, pred.argmax(1), group=None, async_op=False)
        tensor_list_y = torch.cat(tensor_list_y)
        tensor_list_pred = torch.cat(tensor_list_pred)

        # Confusion Matrix
        conf_mat += confusion_matrix(tensor_list_y.cpu().detach().numpy(), tensor_list_pred.cpu().detach().numpy(), labels=np.arange(0,10))

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        losses.append(loss.item())

        # Save batch predictions
        batch_results[batch_n] = {'true':tensor_list_y, 'pred':tensor_list_pred}

        if verbosity == True:
            print(f"\n\nTRAIN on GPU:{gpu}: True Label {y} - Prediction {pred.argmax(1)} - Loss {loss}")
            truevalue = '\t\t'.join(classes[items] for items in y.tolist())
            predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
            print(f"INFO on GPU:{gpu}: TRAIN - True Value\t {truevalue}")
            print(f"INFO on GPU:{gpu}: TRAIN - Predictions\t {predvalues}")

        if batch_n % 25 == 0:
            torch.distributed.reduce(loss, 0)
            """if gpu == 0:
                # print predictions and true values
                #truevalue = '\t\t'.join(classes[items] for items in y.tolist())
                #predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
                #print(f"\n\nINFO on GPU{gpu}: TRAIN - True Value\t {truevalue}")
                #print(f"INFO on GPU{gpu}: TRAIN - Predictions\t {predvalues}")
                #print("INFO: TRAIN - Correctness\t", pred.argmax(1) == y)
                #print(f"INFO: TRAIN - Single Batch Test Accuracy {correct * 100 / batch_size}\n\n")
                loss, current = loss.item(), batch_n * len(X)
                #print(f"loss: {loss:>7f}")"""
        #print(f"conf_mat: {conf_mat}")
        #print(f"batch_results: {batch_results}")

    return torch.tensor(losses, device=f"cuda:{gpu}"), torch.tensor(correct, device=f"cuda:{gpu}"), batch_results, conf_mat

def train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch):
    epoch_losses = []
    training_accuracies = []
    test_losses = []
    test_accuracies = []
    learning_rates = []
    counter = 0 #early stopping counter
    batchwise_results = dict()

    # Learning Rate Scheduler
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=20)

    for i in range(initial_epoch, initial_epoch + epochs):
        if gpu == 0:
            if initial_epoch > 0:
                print(f"\n\nEpoch {i}\n-------------------------------")
            else:
                print(f"\n\nEpoch {i + 1}\n-------------------------------")

        # TRAIN
        losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
        average_loss = torch.mean(losses)
        torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(training_accuracy, 0, torch.distributed.ReduceOp.SUM)

        # TEST
        test_accuracy, test_loss, test_batch_result, test_conf_mat = test_loop(gpu, test_dataloader, model, loss_fn)
        torch.distributed.reduce(test_accuracy, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(test_loss, 0, torch.distributed.ReduceOp.SUM)

        # save results
        batchwise_results[i] = {'train':train_batch_result, 'test':test_batch_result}
        if gpu == 0:  # the following operations are performed only by the process running in the first gpu
            average_loss = average_loss / torch.tensor(gpus, dtype=torch.float)  # average loss among all gpus
            test_accuracy = test_accuracy / torch.tensor(len(test_dataloader.dataset),
                                                         dtype=torch.float) * torch.tensor(100.0)
            training_accuracy = training_accuracy / torch.tensor(len(training_dataloader.dataset),
                                                                 dtype=torch.float) * torch.tensor(100.0)
            test_loss = test_loss / torch.tensor(gpus, dtype=torch.float)
            epoch_losses.append(average_loss.item())
            training_accuracies.append(training_accuracy.item())
            test_losses.append(test_loss.item())
            test_accuracies.append(test_accuracy.item())
            learning_rates.append((optimizer.param_groups[0])["lr"])
            print(f"\nBatch size: {batch_size * int(gpus)}")
            print(f"average Training Loss: {average_loss.item():.6f}")
            print(f"average Test Loss: {test_loss.item():.6f}")
            print(f"\naverage Training Acc: {training_accuracy.item():.6f}")
            print(f"average Test Acc: {test_accuracy.item():.6f}")
            printLearningRate(optimizer)
            scheduler.step(test_loss)

            """# stepwise learning rate decay
            if average_loss.item() <= 0.35:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.007")
                    param_group['lr'] = 0.007
            if average_loss.item() <= 0.30:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.004")
                    param_group['lr'] = 0.004"""

            # saving model checkpoint
            save_checkpoint(model, optimizer, scheduler, i, epoch_losses, training_accuracies, test_losses, test_accuracies, learning_rates,
                            os.path.join(dir_path, f"epoch{i}.pth"), {key: value for key, value in batchwise_results[i].items() if key == 'train'}, {key: value for key, value in batchwise_results[i].items() if key == 'test'}, train_conf_mat, test_conf_mat)
            #TODO: implement ONNX Export
            # early stopping scheduler
            if early_stopping(test_losses) == True:
                counter += 1
                print(f"Early Stopping counter: {counter} of {patience}")
            else:
                counter += 0
            if counter < patience:
                pass
            else:
                print("\n\nEarly Stopping activated")
                print(f"Training stopped at Epoch{i + 1}")
                dist.destroy_process_group()
                exit()
class DistributedWeightedSampler(Sampler):
    def __init__(self, dataset, data_source: Optional[Sized], num_replicas: Optional[int] = None,
                 rank: Optional[int] = None, shuffle: bool = True, seed: int = 0, replacement: bool = True):
        super().__init__(data_source)
        if num_replicas is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            num_replicas = dist.get_world_size()
        if rank is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            rank = dist.get_rank()
        if rank >= num_replicas or rank < 0:
            raise ValueError("Invalid rank {}, rank should be in the interval [0, {}]".format(rank, num_replicas - 1))
        self.dataset = dataset
        self.num_replicas = num_replicas
        self.rank = rank
        self.epoch = 0
        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas))
        self.total_size = self.num_samples * self.num_replicas
        self.shuffle = shuffle
        self.seed = seed
        self.replacement = replacement #sample can be drown again in that row if True

    def calculate_weights(self, targets):
        class_sample_count = np.array([len(np.where(self.dataset.data.y == t)[0]) for t in np.unique(self.dataset.data.y)])
        weight = 1. / class_sample_count
        samples_weight = np.array([weight[t] for t in self.dataset.data.y])
        samples_weight = torch.from_numpy(samples_weight)
        samples_weigth = samples_weight.double()
        return samples_weigth

    def __iter__(self):
        # deterministically shuffle based on epoch
        if self.shuffle:
            g = torch.Generator()
            g.manual_seed(self.seed + self.epoch)
            indices = torch.randperm(len(self.dataset), generator=g).tolist()
        else:
            indices = list(range(len(self.dataset)))

        # add extra samples to make it evenly divisible
        indices += indices[:(self.total_size - len(indices))]
        assert len(indices) == self.total_size

        # subsample
        indices = indices[self.rank:self.total_size:self.num_replicas]
        assert len(indices) == self.num_samples

        # get targets (you can alternatively pass them in __init__, if this op is expensive)
        # data.data.y == labels
        targets = self.dataset.data.y
        targets = targets[self.rank:self.total_size:self.num_replicas]
        #assert len(targets) == self.num_samples
        weights = self.calculate_weights(targets)
        weighted_indices = torch.multinomial(weights, self.num_samples, self.replacement).tolist()

        return iter(weighted_indices)

    def __len__(self):
        return self.num_samples

    def set_epoch(self, epoch):
        self.epoch = epoch
def train(gpu, gpus, world_size):
    torch.manual_seed(0)
    torch.cuda.set_device(gpu)
    try:
        #dist.init_process_group(backend='nccl', world_size=world_size, rank=gpu) #for distributed GPU training
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option
    except RuntimeError:
        print("\n\nINFO:RuntimeError is raised >> Used gloo backend instead of nccl!\n")
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option

    dir_path = None
    if gpu == 0:
        dir_path = "stackgraphConvPool3DPnet"
        createdir(dir_path)
        training_number = next_training_number(dir_path)
        dir_path = os.path.join(dir_path, f"train{training_number}")
        createdir(dir_path)
        #save hyper-parameters in txt protocol file
        save_hyperparameters(dir_path, 'hyperparameters.txt')
        print("\nINFO: Protocol File saved successfully . . .")

        #copy crucial py-files in current train folder
        #shutil.copy2(os.path.basename('__file__'), dir_path)
        #shutil.copy2('stackGraphConvPool3DPnet.py', dir_path)
        #shutil.copy2('shrinkingunit.py', dir_path)
        #shutil.copy2('utilities.py', dir_path)
        #print("\nINFO: Script Files copied successfully . . .")

    model = Classifier(shrinkingLayers, mlpClassifier)

    torch.cuda.set_device(gpu)
    model.cuda(gpu)

    #setting up optimizer
    if optimizer_str == "SGD":
        optimizer = torch.optim.SGD(model.parameters(), learning_rate, momentum=momentum, weight_decay=weight_decay)
    elif optimizer_str == "RMSprop":
        optimizer = torch.optim.RMSprop(model.parameters(), learning_rate, weight_decay=weight_decay)
    else:
        optimizer = torch.optim.Adam(model.parameters(), learning_rate, weight_decay=weight_decay)

    # single-program multiple-data training paradigm (Distributed Data-Parallel Training)
    model = DDP(model, device_ids=[gpu])

    if dimensionality == 3:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))

    training_sampler = DistributedWeightedSampler(training_data, data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    training_dataloader = DataLoader(dataset=training_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                          pin_memory=True, sampler=training_sampler)

    if dimensionality == 3:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))

    test_sampler = DistributedWeightedSampler(test_data,data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    test_dataloader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                      pin_memory=True, sampler=test_sampler)

    """# save sampled data for later result visualisation
    try:
        #export_path = os.path.join("stackgraphConvPool3DPnet", "train" + str(next_training_number("stackgraphConvPool3DPnet")-1))
        #export_sampled_data(training_dataloader, os.path.join(export_path, "train_sampledPoints.pth"))
        #export_sampled_data(test_dataloader, os.path.join(export_path, "test_sampledPoints.pth"))
        print("\nINFO: Sampled 3D data successfully saved . . .")
    except Exception as e:
        print(f"\nERROR: Sampled 3D data could not saved successfully . . . - this process does not executed - caused by {e}")"""

    # weighted CE Loss over all Classes C
    class_sample_count = np.array([len(np.where(training_data.data.y == t)[0]) for t in np.unique(training_data.data.y)])
    weight = 1. / class_sample_count
    weight = torch.from_numpy(weight)
    weight = weight.float()
    loss_fn = nn.CrossEntropyLoss(weight=weight).cuda(gpu)

    # continue training from certain checkpoint
    continue_from_scratch = True if args.resume is None else False
    if continue_from_scratch:
        if gpu == 0:
            print("\nINFO: Train from scratch has started . . .")
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    else:
        checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume
        if gpu == 0:
            print(f"\nINFO: Train has started from certain checkpoint {checkpoint_path.split('/')[2].split('.')[0]} in {checkpoint_path.split('/')[1]} . . .")
        model.load_state_dict(torch.load(checkpoint_path)['model_state_dict'], strict=False)
        optimizer.load_state_dict(torch.load(checkpoint_path)['optimizer_state_dict'])
        final_epoch = (torch.load("stackgraphConvPool3DPnet/" + args.resume)['epoch'])+1
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, final_epoch)
</code>```
```<code>
INFO: Train from scratch has started . . .

Epoch 1
-------------------------------
Exception in thread Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
Thread-7:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [1], in <cell line: 720>()
    734 #change state
    735 if args.train_state == True:
--> 736     train(args.local_rank, gpus, world_size)
    737 else:
    738     infer(args.local_rank, gpus, world_size, args.checkpoint, args.data)

Input In [1], in train(gpu, gpus, world_size)
    672     if gpu == 0:
    673         print("\nINFO: Train from scratch has started . . .")
--> 674     train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    675 else:
    676     checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume

Input In [1], in train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch)
    454         print(f"\n\nEpoch {i + 1}\n-------------------------------")
    456 # TRAIN
--> 457 losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    458 average_loss = torch.mean(losses)
    459 torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)

Input In [1], in training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    249 y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])
    251 # Compute predictions
--> 252 pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])
    254 if overall_classes_loss:
    255     # weighted CE Loss over all classes
    256     loss = loss_fn(pred, y)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:1008, in DistributedDataParallel.forward(self, *inputs, **kwargs)
   1004 if self._join_config.enable:
   1005     # Notify joined ranks whether they should sync in backwards pass or not.
   1006     self._check_global_requires_backward_grad_sync(is_joined_rank=False)
-> 1008 output = self._run_ddp_forward(*inputs, **kwargs)
   1010 # sync params according to location (before/after forward) user
   1011 # specified as part of hook, if hook was specified.
   1012 if self._check_sync_bufs_post_fwd():

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:969, in DistributedDataParallel._run_ddp_forward(self, *inputs, **kwargs)
    962 if self.device_ids:
    963     inputs, kwargs = _to_kwargs(
    964         inputs,
    965         kwargs,
    966         self.device_ids[0],
    967         self.use_side_stream_for_tensor_copies
    968     )
--> 969     return module_to_run(*inputs[0], **kwargs[0])
    970 else:
    971     return module_to_run(*inputs, **kwargs)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:657, in Classifier.forward(self, x, pos)
    655 feature_matrix_batch = pos.unsqueeze(0)
    656 # feature_matrix_batch size = (1,N,I,D) where N=batch number, I=members, D=member dimensionality
--> 657 output = self.neuralNet(feature_matrix_batch)
    658 # output size = (S,N,D) where S= stack size, N=batch number, D'=member dimensionality
    659 output = torch.mean(output, dim=0)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\container.py:139, in Sequential.forward(self, input)
    137 def forward(self, input):
    138     for module in self:
--> 139         input = module(input)
    140     return input

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:448, in ShrinkingUnitStack.forward(self, feature_matrix_batch)
    446 feature_matrix_batch = self.selfCorrStack(feature_matrix_batch)
    447 # feature_matrix_batch size = (S',N,I,D) where S'=stack_size, N=batch number, I=members, D=member dimensionality
--> 448 feature_matrix_batch_, conv_feature_matrix_batch, cluster_index = self.kmeansConvStack(feature_matrix_batch)
    449 feature_matrix_batch = self.localAdaptFeaAggreStack(feature_matrix_batch, conv_feature_matrix_batch)
    450 output = self.graphMaxPoolStack(feature_matrix_batch, cluster_index)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:519, in KMeansConvStack.forward(self, feature_matrix_batch)
    517 def forward(self, feature_matrix_batch: torch.Tensor):
    518     # feature_matrix_batch size = (S,N,I,D) where S=stack size, N=batch number, I=members, D=member dimensionality
--> 519     feature_matrix_batch, conv_feature_matrix_batch, cluster_index = kmeansConvThreader(self.kmeansConvStack,
    520                                                                                feature_matrix_batch)
    521     # feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    522     # conv_feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    523     # cluster_index size = (S,M) where S=stack_size, M=N*I
    524     return feature_matrix_batch, conv_feature_matrix_batch, cluster_index

File ~\Desktop\Forum\unit.py:611, in kmeansConvThreader(modules, input_tensor)
    609 list2_append = list(map(lambda x: x[1], list2_append))
    610 list3_append = list(map(lambda x: x[1], list3_append))
--> 611 return torch.stack(list1_append), torch.stack(list2_append), torch.stack(list3_append)

RuntimeError: stack expects a non-empty TensorList
</code>```
```<code>def forward(self, feature_matrix_batch):
        # feature_matrix_batch size = (N,I,D) where N=batch number, I=members, D=member dimensionality
        N, I, D = feature_matrix_batch.size()
        clusters = []
        for i, feature_matrix in enumerate(feature_matrix_batch):
            kmeans = KMeans(n_clusters=self.k, init=self.kmeansInit, n_init=self.n_init)
            labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
</code>```
```<code>def kmeansConvThreader(modules, input_tensor):
    list1_append = []
    list2_append = []
    list3_append = []
    threads = []
    for i, t in enumerate(input_tensor):
        threads.append(
            Thread(target=kmeansAppender, args=(modules[i], t, list1_append, list2_append, list3_append, i)))
    [t.start() for t in threads]
    [t.join() for t in threads]
    list1_append.sort()
    list2_append.sort()
    list3_append.sort()
    list1_append = list(map(lambda x: x[1], list1_append))
    list2_append = list(map(lambda x: x[1], list2_append))
    list3_append = list(map(lambda x: x[1], list3_append))
    return torch.stack(list1_append), torch.stack(list2_append), torch.stack(list3_append)
</code>```

AttributeError: 'KMeans' object has no attribute 'labels_'
RuntimeError: stack expects a non-empty TensorList

Thanks for your help

Body:
first of all I thank , I tried to train  model with  pytorch but I got the following error:
RuntimeError: stack expects a non-empty TensorList .I am trying to model a extract features point cloud using deep learning in pytorch.
I get the following error . Could anyone help on this? ************** ***************
Thanks!

def training_loop(gpu, training_dataloader, model, loss_fn, optimizer):
    losses = []
    correct = 0
    batch_results = dict()
    conf_mat = np.zeros((10,10))
    for batch_n, batch in enumerate(training_dataloader): #batch[batch, pos, ptr, y]
        batch_size = int(batch.batch.size()[0] / sample_points)

        if dimensionality == 3:
            # Input dim [:,3] for your geometry x,y,z
            X = batch.pos.cuda(non_blocking=True).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                dimensionality), fill_value=0.1)).cuda(gpu)
        else:
            # Input dim [:,6] for your geometry x,y,z and normals nx,ny,nz
            X = torch.cat((batch.pos.cuda(non_blocking=True), batch.normal.cuda(non_blocking=True)), 1).view(batch_size, sample_points, -1) + torch.normal(
                torch.zeros(batch_size, sample_points, dimensionality), torch.full((batch_size, sample_points,
                                                                                dimensionality), fill_value=0.1)).cuda(gpu)

        y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])

        # Compute predictions
        pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])

        if overall_classes_loss:
            # weighted CE Loss over all classes
            loss = loss_fn(pred, y)
        else:
            # weighted batchwise Loss
            sample_count = np.array([[x, batch.y.tolist().count(x)] for x in batch.y])[:,1]
            batch_weights = 1. / sample_count
            batch_weights = torch.from_numpy(batch_weights)
            batch_weights = batch_weights.double()
            loss = element_weighted_loss(pred, batch.y, batch_weights, gpu)

        correct += (pred.argmax(1) == y).type(torch.float).sum().item()
        print(f"Loss: {loss}")

        tensor_list_y =  [torch.ones_like(y) for _ in range(dist.get_world_size())]
        tensor_list_pred = [torch.ones_like(y) for _ in range(dist.get_world_size())]
        torch.distributed.all_gather(tensor_list_y, y, group=None, async_op=False)
        torch.distributed.all_gather(tensor_list_pred, pred.argmax(1), group=None, async_op=False)
        tensor_list_y = torch.cat(tensor_list_y)
        tensor_list_pred = torch.cat(tensor_list_pred)

        # Confusion Matrix
        conf_mat += confusion_matrix(tensor_list_y.cpu().detach().numpy(), tensor_list_pred.cpu().detach().numpy(), labels=np.arange(0,10))

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        losses.append(loss.item())

        # Save batch predictions
        batch_results[batch_n] = {'true':tensor_list_y, 'pred':tensor_list_pred}

        if verbosity == True:
            print(f"\n\nTRAIN on GPU:{gpu}: True Label {y} - Prediction {pred.argmax(1)} - Loss {loss}")
            truevalue = '\t\t'.join(classes[items] for items in y.tolist())
            predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
            print(f"INFO on GPU:{gpu}: TRAIN - True Value\t {truevalue}")
            print(f"INFO on GPU:{gpu}: TRAIN - Predictions\t {predvalues}")

        if batch_n % 25 == 0:
            torch.distributed.reduce(loss, 0)
            """if gpu == 0:
                # print predictions and true values
                #truevalue = '\t\t'.join(classes[items] for items in y.tolist())
                #predvalues = '\t\t'.join(classes[items] for items in pred.argmax(1).tolist())
                #print(f"\n\nINFO on GPU{gpu}: TRAIN - True Value\t {truevalue}")
                #print(f"INFO on GPU{gpu}: TRAIN - Predictions\t {predvalues}")
                #print("INFO: TRAIN - Correctness\t", pred.argmax(1) == y)
                #print(f"INFO: TRAIN - Single Batch Test Accuracy {correct * 100 / batch_size}\n\n")
                loss, current = loss.item(), batch_n * len(X)
                #print(f"loss: {loss:>7f}")"""
        #print(f"conf_mat: {conf_mat}")
        #print(f"batch_results: {batch_results}")

    return torch.tensor(losses, device=f"cuda:{gpu}"), torch.tensor(correct, device=f"cuda:{gpu}"), batch_results, conf_mat

def train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch):
    epoch_losses = []
    training_accuracies = []
    test_losses = []
    test_accuracies = []
    learning_rates = []
    counter = 0 #early stopping counter
    batchwise_results = dict()

    # Learning Rate Scheduler
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=20)

    for i in range(initial_epoch, initial_epoch + epochs):
        if gpu == 0:
            if initial_epoch > 0:
                print(f"\n\nEpoch {i}\n-------------------------------")
            else:
                print(f"\n\nEpoch {i + 1}\n-------------------------------")

        # TRAIN
        losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
        average_loss = torch.mean(losses)
        torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(training_accuracy, 0, torch.distributed.ReduceOp.SUM)

        # TEST
        test_accuracy, test_loss, test_batch_result, test_conf_mat = test_loop(gpu, test_dataloader, model, loss_fn)
        torch.distributed.reduce(test_accuracy, 0, torch.distributed.ReduceOp.SUM)
        torch.distributed.reduce(test_loss, 0, torch.distributed.ReduceOp.SUM)

        # save results
        batchwise_results[i] = {'train':train_batch_result, 'test':test_batch_result}
        if gpu == 0:  # the following operations are performed only by the process running in the first gpu
            average_loss = average_loss / torch.tensor(gpus, dtype=torch.float)  # average loss among all gpus
            test_accuracy = test_accuracy / torch.tensor(len(test_dataloader.dataset),
                                                         dtype=torch.float) * torch.tensor(100.0)
            training_accuracy = training_accuracy / torch.tensor(len(training_dataloader.dataset),
                                                                 dtype=torch.float) * torch.tensor(100.0)
            test_loss = test_loss / torch.tensor(gpus, dtype=torch.float)
            epoch_losses.append(average_loss.item())
            training_accuracies.append(training_accuracy.item())
            test_losses.append(test_loss.item())
            test_accuracies.append(test_accuracy.item())
            learning_rates.append((optimizer.param_groups[0])["lr"])
            print(f"\nBatch size: {batch_size * int(gpus)}")
            print(f"average Training Loss: {average_loss.item():.6f}")
            print(f"average Test Loss: {test_loss.item():.6f}")
            print(f"\naverage Training Acc: {training_accuracy.item():.6f}")
            print(f"average Test Acc: {test_accuracy.item():.6f}")
            printLearningRate(optimizer)
            scheduler.step(test_loss)

            """# stepwise learning rate decay
            if average_loss.item() <= 0.35:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.007")
                    param_group['lr'] = 0.007
            if average_loss.item() <= 0.30:
                for param_group in optimizer.param_groups:
                    print("Learning rate changed to 0.004")
                    param_group['lr'] = 0.004"""

            # saving model checkpoint
            save_checkpoint(model, optimizer, scheduler, i, epoch_losses, training_accuracies, test_losses, test_accuracies, learning_rates,
                            os.path.join(dir_path, f"epoch{i}.pth"), {key: value for key, value in batchwise_results[i].items() if key == 'train'}, {key: value for key, value in batchwise_results[i].items() if key == 'test'}, train_conf_mat, test_conf_mat)
            #TODO: implement ONNX Export
            # early stopping scheduler
            if early_stopping(test_losses) == True:
                counter += 1
                print(f"Early Stopping counter: {counter} of {patience}")
            else:
                counter += 0
            if counter < patience:
                pass
            else:
                print("\n\nEarly Stopping activated")
                print(f"Training stopped at Epoch{i + 1}")
                dist.destroy_process_group()
                exit()
class DistributedWeightedSampler(Sampler):
    def __init__(self, dataset, data_source: Optional[Sized], num_replicas: Optional[int] = None,
                 rank: Optional[int] = None, shuffle: bool = True, seed: int = 0, replacement: bool = True):
        super().__init__(data_source)
        if num_replicas is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            num_replicas = dist.get_world_size()
        if rank is None:
            if not dist.is_available():
                raise RuntimeError("Requires distributed package to be available")
            rank = dist.get_rank()
        if rank >= num_replicas or rank < 0:
            raise ValueError("Invalid rank {}, rank should be in the interval [0, {}]".format(rank, num_replicas - 1))
        self.dataset = dataset
        self.num_replicas = num_replicas
        self.rank = rank
        self.epoch = 0
        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas))
        self.total_size = self.num_samples * self.num_replicas
        self.shuffle = shuffle
        self.seed = seed
        self.replacement = replacement #sample can be drown again in that row if True

    def calculate_weights(self, targets):
        class_sample_count = np.array([len(np.where(self.dataset.data.y == t)[0]) for t in np.unique(self.dataset.data.y)])
        weight = 1. / class_sample_count
        samples_weight = np.array([weight[t] for t in self.dataset.data.y])
        samples_weight = torch.from_numpy(samples_weight)
        samples_weigth = samples_weight.double()
        return samples_weigth

    def __iter__(self):
        # deterministically shuffle based on epoch
        if self.shuffle:
            g = torch.Generator()
            g.manual_seed(self.seed + self.epoch)
            indices = torch.randperm(len(self.dataset), generator=g).tolist()
        else:
            indices = list(range(len(self.dataset)))

        # add extra samples to make it evenly divisible
        indices += indices[:(self.total_size - len(indices))]
        assert len(indices) == self.total_size

        # subsample
        indices = indices[self.rank:self.total_size:self.num_replicas]
        assert len(indices) == self.num_samples

        # get targets (you can alternatively pass them in __init__, if this op is expensive)
        # data.data.y == labels
        targets = self.dataset.data.y
        targets = targets[self.rank:self.total_size:self.num_replicas]
        #assert len(targets) == self.num_samples
        weights = self.calculate_weights(targets)
        weighted_indices = torch.multinomial(weights, self.num_samples, self.replacement).tolist()

        return iter(weighted_indices)

    def __len__(self):
        return self.num_samples

    def set_epoch(self, epoch):
        self.epoch = epoch
def train(gpu, gpus, world_size):
    torch.manual_seed(0)
    torch.cuda.set_device(gpu)
    try:
        #dist.init_process_group(backend='nccl', world_size=world_size, rank=gpu) #for distributed GPU training
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option
    except RuntimeError:
        print("\n\nINFO:RuntimeError is raised >> Used gloo backend instead of nccl!\n")
        dist.init_process_group(backend='gloo', world_size=world_size, rank=gpu) #as a fallback option

    dir_path = None
    if gpu == 0:
        dir_path = "stackgraphConvPool3DPnet"
        createdir(dir_path)
        training_number = next_training_number(dir_path)
        dir_path = os.path.join(dir_path, f"train{training_number}")
        createdir(dir_path)
        #save hyper-parameters in txt protocol file
        save_hyperparameters(dir_path, 'hyperparameters.txt')
        print("\nINFO: Protocol File saved successfully . . .")

        #copy crucial py-files in current train folder
        #shutil.copy2(os.path.basename('__file__'), dir_path)
        #shutil.copy2('stackGraphConvPool3DPnet.py', dir_path)
        #shutil.copy2('shrinkingunit.py', dir_path)
        #shutil.copy2('utilities.py', dir_path)
        #print("\nINFO: Script Files copied successfully . . .")

    model = Classifier(shrinkingLayers, mlpClassifier)

    torch.cuda.set_device(gpu)
    model.cuda(gpu)

    #setting up optimizer
    if optimizer_str == "SGD":
        optimizer = torch.optim.SGD(model.parameters(), learning_rate, momentum=momentum, weight_decay=weight_decay)
    elif optimizer_str == "RMSprop":
        optimizer = torch.optim.RMSprop(model.parameters(), learning_rate, weight_decay=weight_decay)
    else:
        optimizer = torch.optim.Adam(model.parameters(), learning_rate, weight_decay=weight_decay)

    # single-program multiple-data training paradigm (Distributed Data-Parallel Training)
    model = DDP(model, device_ids=[gpu])

    if dimensionality == 3:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        training_data = ModelNet("ModelNet10_train_data", transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))

    training_sampler = DistributedWeightedSampler(training_data, data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    training_dataloader = DataLoader(dataset=training_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                          pin_memory=True, sampler=training_sampler)

    if dimensionality == 3:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(SamplePoints(num=sample_points)(x)))
    else:
        test_data = ModelNet("ModelNet10_test_data", train=False, transform=lambda x: NormalizeScale()(NormalizeRotation()(SamplePoints(num=sample_points, remove_faces=True, include_normals=True)(x))))

    test_sampler = DistributedWeightedSampler(test_data,data_source=None, num_replicas=world_size) #weight unbalanced classes by 1/cls_count
    test_dataloader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=data_shuffle, num_workers=0,
                                      pin_memory=True, sampler=test_sampler)

    """# save sampled data for later result visualisation
    try:
        #export_path = os.path.join("stackgraphConvPool3DPnet", "train" + str(next_training_number("stackgraphConvPool3DPnet")-1))
        #export_sampled_data(training_dataloader, os.path.join(export_path, "train_sampledPoints.pth"))
        #export_sampled_data(test_dataloader, os.path.join(export_path, "test_sampledPoints.pth"))
        print("\nINFO: Sampled 3D data successfully saved . . .")
    except Exception as e:
        print(f"\nERROR: Sampled 3D data could not saved successfully . . . - this process does not executed - caused by {e}")"""

    # weighted CE Loss over all Classes C
    class_sample_count = np.array([len(np.where(training_data.data.y == t)[0]) for t in np.unique(training_data.data.y)])
    weight = 1. / class_sample_count
    weight = torch.from_numpy(weight)
    weight = weight.float()
    loss_fn = nn.CrossEntropyLoss(weight=weight).cuda(gpu)

    # continue training from certain checkpoint
    continue_from_scratch = True if args.resume is None else False
    if continue_from_scratch:
        if gpu == 0:
            print("\nINFO: Train from scratch has started . . .")
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    else:
        checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume
        if gpu == 0:
            print(f"\nINFO: Train has started from certain checkpoint {checkpoint_path.split('/')[2].split('.')[0]} in {checkpoint_path.split('/')[1]} . . .")
        model.load_state_dict(torch.load(checkpoint_path)['model_state_dict'], strict=False)
        optimizer.load_state_dict(torch.load(checkpoint_path)['optimizer_state_dict'])
        final_epoch = (torch.load("stackgraphConvPool3DPnet/" + args.resume)['epoch'])+1
        train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, final_epoch)

INFO: Train from scratch has started . . .

Epoch 1
-------------------------------
Exception in thread Exception in thread Thread-8:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
Thread-7:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    self._target(*self._args, **self._kwargs)
  File ~\Desktop\Forum\unit.py", line 615, in kmeansAppender
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    x, y, z = module(input)
  File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 1130, in _call_impl
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
    return forward_call(*input, **kwargs)
  File ~\Desktop\Forum\unit.py", line 148, in forward
    labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)
AttributeError: 'KMeans' object has no attribute 'labels_'
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [1], in <cell line: 720>()
    734 #change state
    735 if args.train_state == True:
--> 736     train(args.local_rank, gpus, world_size)
    737 else:
    738     infer(args.local_rank, gpus, world_size, args.checkpoint, args.data)

Input In [1], in train(gpu, gpus, world_size)
    672     if gpu == 0:
    673         print("\nINFO: Train from scratch has started . . .")
--> 674     train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, None, dir_path, 0)
    675 else:
    676     checkpoint_path = "stackgraphConvPool3DPnet/" + args.resume

Input In [1], in train_optimisation(gpu, gpus, training_dataloader, test_dataloader, model, loss_fn, optimizer, scheduler, dir_path, initial_epoch)
    454         print(f"\n\nEpoch {i + 1}\n-------------------------------")
    456 # TRAIN
--> 457 losses, training_accuracy, train_batch_result, train_conf_mat = training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    458 average_loss = torch.mean(losses)
    459 torch.distributed.reduce(average_loss, 0, torch.distributed.ReduceOp.SUM)

Input In [1], in training_loop(gpu, training_dataloader, model, loss_fn, optimizer)
    249 y = batch.y.cuda(non_blocking=True).flatten() #size (batch_size) --> torch.Size([8])
    251 # Compute predictions
--> 252 pred = model(None, X) #size (batch_size,classes) --> torch.Size([8, 10])
    254 if overall_classes_loss:
    255     # weighted CE Loss over all classes
    256     loss = loss_fn(pred, y)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:1008, in DistributedDataParallel.forward(self, *inputs, **kwargs)
   1004 if self._join_config.enable:
   1005     # Notify joined ranks whether they should sync in backwards pass or not.
   1006     self._check_global_requires_backward_grad_sync(is_joined_rank=False)
-> 1008 output = self._run_ddp_forward(*inputs, **kwargs)
   1010 # sync params according to location (before/after forward) user
   1011 # specified as part of hook, if hook was specified.
   1012 if self._check_sync_bufs_post_fwd():

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\parallel\distributed.py:969, in DistributedDataParallel._run_ddp_forward(self, *inputs, **kwargs)
    962 if self.device_ids:
    963     inputs, kwargs = _to_kwargs(
    964         inputs,
    965         kwargs,
    966         self.device_ids[0],
    967         self.use_side_stream_for_tensor_copies
    968     )
--> 969     return module_to_run(*inputs[0], **kwargs[0])
    970 else:
    971     return module_to_run(*inputs, **kwargs)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:657, in Classifier.forward(self, x, pos)
    655 feature_matrix_batch = pos.unsqueeze(0)
    656 # feature_matrix_batch size = (1,N,I,D) where N=batch number, I=members, D=member dimensionality
--> 657 output = self.neuralNet(feature_matrix_batch)
    658 # output size = (S,N,D) where S= stack size, N=batch number, D'=member dimensionality
    659 output = torch.mean(output, dim=0)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\container.py:139, in Sequential.forward(self, input)
    137 def forward(self, input):
    138     for module in self:
--> 139         input = module(input)
    140     return input

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:448, in ShrinkingUnitStack.forward(self, feature_matrix_batch)
    446 feature_matrix_batch = self.selfCorrStack(feature_matrix_batch)
    447 # feature_matrix_batch size = (S',N,I,D) where S'=stack_size, N=batch number, I=members, D=member dimensionality
--> 448 feature_matrix_batch_, conv_feature_matrix_batch, cluster_index = self.kmeansConvStack(feature_matrix_batch)
    449 feature_matrix_batch = self.localAdaptFeaAggreStack(feature_matrix_batch, conv_feature_matrix_batch)
    450 output = self.graphMaxPoolStack(feature_matrix_batch, cluster_index)

File C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
   1126 # If we don't have any hooks, we want to skip the rest of the logic in
   1127 # this function, and just call forward.
   1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130     return forward_call(*input, **kwargs)
   1131 # Do not call functions when jit is used
   1132 full_backward_hooks, non_full_backward_hooks = [], []

File ~\Desktop\Forum\unit.py:519, in KMeansConvStack.forward(self, feature_matrix_batch)
    517 def forward(self, feature_matrix_batch: torch.Tensor):
    518     # feature_matrix_batch size = (S,N,I,D) where S=stack size, N=batch number, I=members, D=member dimensionality
--> 519     feature_matrix_batch, conv_feature_matrix_batch, cluster_index = kmeansConvThreader(self.kmeansConvStack,
    520                                                                                feature_matrix_batch)
    521     # feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    522     # conv_feature_matrix_batch size = (S,N,I,D) where where S=stack_size, N=batch number, I=members, D=member dimensionality
    523     # cluster_index size = (S,M) where S=stack_size, M=N*I
    524     return feature_matrix_batch, conv_feature_matrix_batch, cluster_index

File ~\Desktop\Forum\unit.py:611, in kmeansConvThreader(modules, input_tensor)
    609 list2_append = list(map(lambda x: x[1], list2_append))
    610 list3_append = list(map(lambda x: x[1], list3_append))
--> 611 return torch.stack(list1_append), torch.stack(list2_append), torch.stack(list3_append)

RuntimeError: stack expects a non-empty TensorList

def forward(self, feature_matrix_batch):
        # feature_matrix_batch size = (N,I,D) where N=batch number, I=members, D=member dimensionality
        N, I, D = feature_matrix_batch.size()
        clusters = []
        for i, feature_matrix in enumerate(feature_matrix_batch):
            kmeans = KMeans(n_clusters=self.k, init=self.kmeansInit, n_init=self.n_init)
            labels = np.apply_along_axis(lambda x: x + (i*self.k), axis=0, arr=kmeans.labels_)

def kmeansConvThreader(modules, input_tensor):
    list1_append = []
    list2_append = []
    list3_append = []
    threads = []
    for i, t in enumerate(input_tensor):
        threads.append(
            Thread(target=kmeansAppender, args=(modules[i], t, list1_append, list2_append, list3_append, i)))
    [t.start() for t in threads]
    [t.join() for t in threads]
    list1_append.sort()
    list2_append.sort()
    list3_append.sort()
    list1_append = list(map(lambda x: x[1], list1_append))
    list2_append = list(map(lambda x: x[1], list2_append))
    list3_append = list(map(lambda x: x[1], list3_append))
    return torch.stack(list1_append), torch.stack(list2_append), torch.stack(list3_append)

AttributeError: 'KMeans' object has no attribute 'labels_'
RuntimeError: stack expects a non-empty TensorList

Thanks for your help


问:
open failed: ENOENT (No such file or directory) even when I'm not trying to open any file
I had app where you can read books from pdf url, fnd it worked well but book loads everytime i open book read page, then i wanted to save pdf first time i open page, and i was watching some tutorial for it, and first thing i did was that i declared this line in Manifest "

```<code><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</code>```

"

Then without writing any code i launched app but the books did not load as if there was no internet connection, but there was! So then i deleted that Write External Storage stroke and issue did not gone, from there i can't load books as i did usual.

SOLUTION: The solution was simple, and it's here: https://stackoverflow.com/a/49953004/19915097

Also good explanation of how loading data from firebase database works:
https://stackoverflow.com/a/47853774/19915097

Body:
I had app where you can read books from pdf url, fnd it worked well but book loads everytime i open book read page, then i wanted to save pdf first time i open page, and i was watching some tutorial for it, and first thing i did was that i declared this line in Manifest "

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

"

Then without writing any code i launched app but the books did not load as if there was no internet connection, but there was! So then i deleted that Write External Storage stroke and issue did not gone, from there i can't load books as i did usual.

SOLUTION: The solution was simple, and it's here: https://stackoverflow.com/a/49953004/19915097

Also good explanation of how loading data from firebase database works:
https://stackoverflow.com/a/47853774/19915097