问:
Reading matrices of unkown dimension
I'm trying to read a matrix from a file formatted in this way

```
1 2 3 4
4 5 6 7
8 9 10 11
*
1 0 1
0 1 1
1 1 1]
```

but I don't know how to pass the multidimensional array with its dimension given by rows[] and cols[] arrays to the function read_matrix().

I am able to get the correct dimension of the two matrices

```<code>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int get_dim(char *file, int *r, int *col);
/*gets the dimension and type of operation*/

void read_matrix(char *file, int (*matA)[], int(*matB)[], int *m, int *n);

int main (int argc, char *argv[]){

    int i,j;
    int rows[2]= {0,1}; /* The last line of the file does not contain '\n' */
    int cols[2]= {0,0};
    int operation; /*type of operation 1 for * and 2 for + */

    operation = get_dim(argv[1], rows, cols);

    int A[rows[0]][cols[0]];
    int B[rows[1]][cols[1]];

    printf("A is a matrix %d x %d\n",rows[0], cols[0]);

    if(operation != 0)
        printf("B is a matrix %d x %d\n", rows[1], cols[1]);

    read_matrix(argv[1], A, B, rows, cols);

    /*printing the matrices */

    for(i = 0; i < rows[0]; i++){
        for(j=0; j < cols[0]; j++){
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }

    printf("*\n");

     for(i = 0; i < rows[1]; i++){
        for(j=0; j< cols[1]; j++){
            printf("%2d ", B[i][j]);
        }
        printf("\n");
    }
    return 0;
}

int get_dim(char *file, int *r, int *col){

   FILE *fp;
   int c;
   int op=0;
   int n =0; /*to check all coefficients in a row */

   /* opening file for reading */
   fp = fopen(file, "r");

   if(fp == NULL) {
      perror("Error opening file");
   }

   while ( (c = getc(fp)) != ']')
   {
       if(isdigit(c) && n==0){
           if(op == 0)
               col[0]++;
           else
               col[1]++;
       }

    //Count whenever new line is encountered
    if (c == '\n'){
        n=1;
        if(op == 0)
            r[0]++;
        else
            r[1]++;
    }

        if(c == '*'){
            op=1;
            n =0;
            c = getc(fp);
        }
        else if(c == '+'){
            op=2;
            c = getc(fp);
        }

        //take next character from file.
    }
    fclose(fp);
    return op;
}

void read_matrix(char *file, int (*matA)[], int(*matB)[], int *m, int *n){

    int i,j;
    FILE *fp;

    if( (fp = fopen(file, "r")) != NULL ){

        for(i=0; i < m[0]; i++)
            for(j=0; j < n[0]; j++)
                fscanf(fp, "%d", &matA[i][j]);

        /*skip the line containing the character operator */
        while ( fgetc(fp) != '\n')
            fgetc(fp);

        for(i=0; i < m[1]; i++)
            for(j=0; j < n[1]; j++)
                fscanf(fp, "%d", &matB[i][j]);
    }

    fclose(fp);
}
</code>```

I should define the pointers this way: int(*matA)[cols[0]] and int(*matB)[cols[1]].
In read_matrix() by declaring this pointer: int(*matB)[] I get the error : invalid use of array with unspecified bounds, that I understand. But the bound is determined by the get_dim() function.

答:
The result of the get_dim function is determined at run-time, and the size static arrays like matA must be determined at compile time. As an example, take this code:

```<code>volatile size_t length = 5;
int myArray[length];
</code>```

Or another example:

```<code>size_t length;
//take input from the user...
int myArray[length]
</code>```

These examples would not compile because length is only able to be determined at run-time.

You would have to use dynamically allocated arrays to do what you want to do.

Title: Reading matrices of unkown dimension

Body:
I'm trying to read a matrix from a file formatted in this way

1 2 3 4
4 5 6 7
8 9 10 11
*
1 0 1
0 1 1
1 1 1]

but I don't know how to pass the multidimensional array with its dimension given by rows[] and cols[] arrays to the function read_matrix().

I am able to get the correct dimension of the two matrices

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int get_dim(char *file, int *r, int *col);
/*gets the dimension and type of operation*/

void read_matrix(char *file, int (*matA)[], int(*matB)[], int *m, int *n);

int main (int argc, char *argv[]){

    int i,j;
    int rows[2]= {0,1}; /* The last line of the file does not contain '\n' */
    int cols[2]= {0,0};
    int operation; /*type of operation 1 for * and 2 for + */

    operation = get_dim(argv[1], rows, cols);

    int A[rows[0]][cols[0]];
    int B[rows[1]][cols[1]];

    printf("A is a matrix %d x %d\n",rows[0], cols[0]);

    if(operation != 0)
        printf("B is a matrix %d x %d\n", rows[1], cols[1]);

    read_matrix(argv[1], A, B, rows, cols);

    /*printing the matrices */

    for(i = 0; i < rows[0]; i++){
        for(j=0; j < cols[0]; j++){
            printf("%d ", A[i][j]);
        }
        printf("\n");
    }

    printf("*\n");

     for(i = 0; i < rows[1]; i++){
        for(j=0; j< cols[1]; j++){
            printf("%2d ", B[i][j]);
        }
        printf("\n");
    }
    return 0;
}

int get_dim(char *file, int *r, int *col){

   FILE *fp;
   int c;
   int op=0;
   int n =0; /*to check all coefficients in a row */

   /* opening file for reading */
   fp = fopen(file, "r");

   if(fp == NULL) {
      perror("Error opening file");
   }

   while ( (c = getc(fp)) != ']')
   {
       if(isdigit(c) && n==0){
           if(op == 0)
               col[0]++;
           else
               col[1]++;
       }

    //Count whenever new line is encountered
    if (c == '\n'){
        n=1;
        if(op == 0)
            r[0]++;
        else
            r[1]++;
    }

        if(c == '*'){
            op=1;
            n =0;
            c = getc(fp);
        }
        else if(c == '+'){
            op=2;
            c = getc(fp);
        }

        //take next character from file.
    }
    fclose(fp);
    return op;
}

void read_matrix(char *file, int (*matA)[], int(*matB)[], int *m, int *n){

    int i,j;
    FILE *fp;

    if( (fp = fopen(file, "r")) != NULL ){

        for(i=0; i < m[0]; i++)
            for(j=0; j < n[0]; j++)
                fscanf(fp, "%d", &matA[i][j]);

        /*skip the line containing the character operator */
        while ( fgetc(fp) != '\n')
            fgetc(fp);

        for(i=0; i < m[1]; i++)
            for(j=0; j < n[1]; j++)
                fscanf(fp, "%d", &matB[i][j]);
    }

    fclose(fp);
}

I should define the pointers this way: int(*matA)[cols[0]] and int(*matB)[cols[1]].
In read_matrix() by declaring this pointer: int(*matB)[] I get the error : invalid use of array with unspecified bounds, that I understand. But the bound is determined by the get_dim() function.

Body:
The result of the get_dim function is determined at run-time, and the size static arrays like matA must be determined at compile time. As an example, take this code:

volatile size_t length = 5;
int myArray[length];

Or another example:

size_t length;
//take input from the user...
int myArray[length]

These examples would not compile because length is only able to be determined at run-time.

You would have to use dynamically allocated arrays to do what you want to do.


来源: stackexchange

问:
Formatting in netbeans?
I want to know how can I configure my netbeans ide to format my code in my specific need.
I need all my assignment in same line to easily distinguish it.
for eg:</p>

```<code> $a    = 1;
 $b    = 1;
 $c    = 1;
 $a++;
 some code

 $d    = 1;
</code>```

答:
Based on your sample code, I'm assuming that you want to do this for PHP. If so, then you can do it as follows:

Select Tools > Options > Editor, then click the Formatting tab.

Select PHP from the Language drop list, then Alignment from the Category drop list.

A code sample will be displayed in the Preview window on the right side of the screen which includes some variable assignments near the end of the code:

Under Group Multiline Alignment check the Assignment box. Note that the assignment operators (=) in the code preview are now aligned:

Notes:

The column position used for aligning the assignment operators is dynamic, based on the length of the longest variable name. I don't think it is possible to place the assignment operator in a specific column as suggested by your code example.

This approach is specific to PHP, and can't be used for formatting code in other languages such as Java or JavaScript.

ContentLicense: CC BY-SA 4.0

Title: Formatting in netbeans?

Body:
I want to know how can I configure my netbeans ide to format my code in my specific need.
I need all my assignment in same line to easily distinguish it.
for eg:

 $a    = 1;
 $b    = 1;
 $c    = 1;
 $a++;
 some code

 $d    = 1;


问:
Read tab delimited data to array in C
I have an input file in text format that looks like:

```<code>G:  5   10  20  30
C:  24  49  4.0 30.0
</code>```

I'd like to set each of these to an array, array, respectively. I saw from this answer reading input parameters from a text file with C, a way to read some of the values, but how would I get the arrays G and C?

EDIT:

If I removed G:, and C: from the .txt file I could just run a for loop.

```<code>double *conc = (double*)malloc(properConfigs*sizeof(double));
double *G = (double*)malloc(properConfigs*sizeof(double));

for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &G[i]);
for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &conc[i]);
</code>```

This would work, but I'd like to be able to account for someone saving the .txt file in a different order or at some point adding more rows (with different parameters).

答:
Looks like your issue is atof() in c discards any white space after the first valid number. If you want to get all of the numbers you will have to split tmpstr2 and do each element separately in atof().

You can use strtok to split it into tokens then use atof() on each.

```<code>char temp[];
char *nums;
nums = strtok(temp, " \t");
int count = 0;
while (nums != NULL)
{
    G[count] = atof(chrs);
    nums = strtok(NULL, " \t");
    count++;
}
</code>```

Of course that is if you know before hand how many numbers you are going to get.

View this article for more info: Split string with delimiters in C

Title: Read tab delimited data to array in C

Body:
I have an input file in text format that looks like:

G:  5   10  20  30
C:  24  49  4.0 30.0

I'd like to set each of these to an array, array, respectively. I saw from this answer reading input parameters from a text file with C, a way to read some of the values, but how would I get the arrays G and C?

EDIT:

If I removed G:, and C: from the .txt file I could just run a for loop.

double *conc = (double*)malloc(properConfigs*sizeof(double));
double *G = (double*)malloc(properConfigs*sizeof(double));

for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &G[i]);
for (int i=0;i<properConfigs;i++)
    fscanf(inputfile,"%lf", &conc[i]);

This would work, but I'd like to be able to account for someone saving the .txt file in a different order or at some point adding more rows (with different parameters).

Body:
Looks like your issue is atof() in c discards any white space after the first valid number. If you want to get all of the numbers you will have to split tmpstr2 and do each element separately in atof().

You can use strtok to split it into tokens then use atof() on each.

char temp[];
char *nums;
nums = strtok(temp, " \t");
int count = 0;
while (nums != NULL)
{
    G[count] = atof(chrs);
    nums = strtok(NULL, " \t");
    count++;
}

Of course that is if you know before hand how many numbers you are going to get.

View this article for more info: Split string with delimiters in C


问:
How can I solve crash in Xamarin Forms UWP app "The parameter is incorrect."
I have a Xamarin Forms app which works fine on iOS and Android. I am adding UWP support to it, and going through each page fixing issues as I go. I've recently run into a crash on one of my pages which gives me the following stack:

```<code>System.ArgumentException: The parameter is incorrect.

element
   at Windows.UI.Xaml.VisualStateManager.GetVisualStateGroups(FrameworkElement obj)
   at Xamarin.Forms.Platform.UWP.SwitchRenderer.UpdateOnColor()
   at Xamarin.Forms.Platform.UWP.SwitchRenderer.OnControlLoaded(Object sender, RoutedEventArgs e)
</code>```

The crash happens after I push the page that contains switches but I don't know exactly what might be causing it and the error message doesn't give any good information.

How can I diagnose this or fix the problem?

答:
As @Jason linked, this is a bug in Xamarin Forms 3.6.0.2XXXX

I upgraded to Xamarin Forms 3.6.0.344457 and that solved the problem.

Body:
I have a Xamarin Forms app which works fine on iOS and Android. I am adding UWP support to it, and going through each page fixing issues as I go. I've recently run into a crash on one of my pages which gives me the following stack:

System.ArgumentException: The parameter is incorrect.

element
   at Windows.UI.Xaml.VisualStateManager.GetVisualStateGroups(FrameworkElement obj)
   at Xamarin.Forms.Platform.UWP.SwitchRenderer.UpdateOnColor()
   at Xamarin.Forms.Platform.UWP.SwitchRenderer.OnControlLoaded(Object sender, RoutedEventArgs e)

The crash happens after I push the page that contains switches but I don't know exactly what might be causing it and the error message doesn't give any good information.

How can I diagnose this or fix the problem?


问:
Contains function in pandas dataframe column (AttributeError: 'str' object has no attribute 'str'
I'm trying to search in string in dataframe column by using contains

1.

```<code>for idx, row in df.iterrows():
  if(row['name'].str.contains('abc')):
</code>```

the above code throw this error

```<code>AttributeError: 'str' object has no attribute 'str'
</code>```

2.

```<code>for idx, row in df.iterrows():
      if(row['name'].contains('abc')):
</code>```

and the second code throw this error

```<code>AttributeError: 'str' object has no attribute 'contains'
</code>```

答:
You should iterate over the columns to search for your string, i.e.:

for column in df.columns:
    df[column].str.contains('some_value')
```

<p>I'm unsure how you're going to use this, but if you simply want to know if any of the rows in a column contain the string, you can use <code>.any()</code>. This will return <code>True</code> or <code>False</code>. While the code above returns you a series</p>

<pre class="lang-py prettyprint-override"><code>for column in df.columns:
    df[column].str.contains('some_value').any()
</code>```

Body:
I'm trying to search in string in dataframe column by using contains

1.

for idx, row in df.iterrows():
  if(row['name'].str.contains('abc')):

the above code throw this error

AttributeError: 'str' object has no attribute 'str'

2.

for idx, row in df.iterrows():
      if(row['name'].contains('abc')):

and the second code throw this error

AttributeError: 'str' object has no attribute 'contains'

Body:
You should iterate over the columns to search for your string, i.e.:

for column in df.columns:
    df[column].str.contains('some_value')

I'm unsure how you're going to use this, but if you simply want to know if any of the rows in a column contain the string, you can use .any(). This will return True or False. While the code above returns you a series

for column in df.columns:
    df[column].str.contains('some_value').any()


问:
R measuring distance from a coastline
I have a set of coordinates:

```<code>d1 <- data_frame(
title = c("base1", "base2", "base3", "base4"),
lat = c(57.3, 58.8, 47.2, 57.8, 65.4, 56.7, 53.3),
long = c(0.4, 3.4, 3.5, 1.2, 1.5, 2.6, 2.7))
</code>```

I would like to know whether the coordinates fall on land, in the sea, or are 3 miles inside a coastline. The coordinates should fall somewhere within the UK, so I know that I need to draw a shape file of the UK and plot the points onto it.

I just don't know how to measure whether the points fall in the sea, land or 2 miles from the coast. Obviously I can tell from looking at a map where they fall, but what I would like is  to add another column to my data set so it looks like this:

```<code> d2 <- data_frame(
title = c("base1", "base2", "base3", "base4", "base5", "base6", "base7"),
lat = c(57.3, 58.8, 47.2, 57.8, 65.4, 56.7, 53.3),
long = c(0.4, 3.4, 3.5, 1.2, 1.5, 2.6, 2.7),
where = c("land", "land", "sea", "coast", "land", "sea", "coast"))
</code>```

note that the data in d2 column 'where' is illustrative, these lat/long points may all be on land, or something else

答:
For a faster implementation of geosphere:::dist2Line that uses purrr for efficient looping and progress for a progress bar, thus retaining the accuracy of Chris' first answer, see below:

```<code>library(geosphere)
library(purr)
library(progress)

spDistPoint2Line <- function (p, line, distfun)
{
  ## rewrite of internal function from geosphere
  test <- !sp::is.projected(line)
  if (!isTRUE(test)) {
    if (is.na(test)) {
      warning("Coordinate reference system of SpatialPolygons object is not set. Assuming it is degrees (longitude/latitude)!")
    }
    else {
      stop("Points are projected. They should be in degrees (longitude/latitude)")
    }
  }

  x <- line@lines
  n <- length(x)
  res <- matrix(nrow = nrow(p), ncol = 3)
  colnames(res) <- c("distance", "lon", "lat")

  line_coords <- map(x, ~(map(.@Lines, ~(.@coords)))) #basically an unlist
  pb <- progress_bar$new(
    total = length(line_coords),
    format = "(:spin) :current of :total, :percent, eta: :eta"
  )

  res[] <- Inf
  result <- reduce(
    .x = line_coords,
    .init = res,
    .f = function(res, crd){
      pb$tick()
      crd <- crd[[1]]
      r <- dist2Line(p, crd, distfun) # have to live without ID
      k <- r[, 1] < res[, 1]
      res[k, ] <- r[k, ]
      return(res)
    }
  )
  return(result)
}

dist2Line <- function (p, line, distfun = distGeo)
{
  p <- geosphere:::.pointsToMatrix(p)
  if (inherits(line, "SpatialPolygons")) {
    line <- methods::as(line, "SpatialLines")
  }
  if (inherits(line, "SpatialLines")) {
    return(spDistPoint2Line(p, line, distfun))
  }

  line <- geosphere:::.pointsToMatrix(line)
  line1 <- line[-nrow(line), , drop = FALSE]
  line2 <- line[-1, , drop = FALSE]
  seglength <- distfun(line1, line2)

  res <-
    p %>%
      array_branch(1) %>%
      map(
        function(xy){
          crossdist <- abs(dist2gc(line1, line2, xy))
          trackdist1 <- alongTrackDistance(line1, line2, xy)
          trackdist2 <- alongTrackDistance(line2, line1, xy)
          mintrackdist <- pmin(trackdist1, trackdist2)
          maxtrackdist <- pmax(trackdist1, trackdist2)
          crossdist[maxtrackdist >= seglength] <- NA
          nodedist <- distfun(xy, line)
          warnopt = getOption("warn")
          options(warn = -1)
          distmin1 <- min(nodedist, na.rm = TRUE)
          distmin2 <- min(crossdist, na.rm = TRUE)
          options(warn = warnopt)
          if (distmin1 <= distmin2) {
            j <- which.min(nodedist)
            return(c(distmin1, line[j, ]))
          }
          else {
            j <- which.min(crossdist)
            if (trackdist1[j] < trackdist2[j]) {
              bear <- bearing(line1[j, ], line2[j, ])
              pt <- destPoint(line1[j, ], bear, mintrackdist[j])
              return(c(crossdist[j], pt))
            }
            else {
              bear <- bearing(line2[j, ], line1[j, ])
              pt <- destPoint(line2[j, ], bear, mintrackdist[j])
              return(c(crossdist[j], pt))
            }
          }
        }
      ) %>%
      simplify %>%
      matrix(ncol = 3, byrow = TRUE)

  colnames(res) <- c("distance", "lon", "lat")
  return(res)
}
</code>```

Title: R measuring distance from a coastline

Body:
I have a set of coordinates:

d1 <- data_frame(
title = c("base1", "base2", "base3", "base4"),
lat = c(57.3, 58.8, 47.2, 57.8, 65.4, 56.7, 53.3),
long = c(0.4, 3.4, 3.5, 1.2, 1.5, 2.6, 2.7))

I would like to know whether the coordinates fall on land, in the sea, or are 3 miles inside a coastline. The coordinates should fall somewhere within the UK, so I know that I need to draw a shape file of the UK and plot the points onto it.

I just don't know how to measure whether the points fall in the sea, land or 2 miles from the coast. Obviously I can tell from looking at a map where they fall, but what I would like is  to add another column to my data set so it looks like this:

 d2 <- data_frame(
title = c("base1", "base2", "base3", "base4", "base5", "base6", "base7"),
lat = c(57.3, 58.8, 47.2, 57.8, 65.4, 56.7, 53.3),
long = c(0.4, 3.4, 3.5, 1.2, 1.5, 2.6, 2.7),
where = c("land", "land", "sea", "coast", "land", "sea", "coast"))

note that the data in d2 column 'where' is illustrative, these lat/long points may all be on land, or something else

Body:
For a faster implementation of geosphere:::dist2Line that uses purrr for efficient looping and progress for a progress bar, thus retaining the accuracy of Chris' first answer, see below:

library(geosphere)
library(purr)
library(progress)

spDistPoint2Line <- function (p, line, distfun)
{
  ## rewrite of internal function from geosphere
  test <- !sp::is.projected(line)
  if (!isTRUE(test)) {
    if (is.na(test)) {
      warning("Coordinate reference system of SpatialPolygons object is not set. Assuming it is degrees (longitude/latitude)!")
    }
    else {
      stop("Points are projected. They should be in degrees (longitude/latitude)")
    }
  }

  x <- line@lines
  n <- length(x)
  res <- matrix(nrow = nrow(p), ncol = 3)
  colnames(res) <- c("distance", "lon", "lat")

  line_coords <- map(x, ~(map(.@Lines, ~(.@coords)))) #basically an unlist
  pb <- progress_bar$new(
    total = length(line_coords),
    format = "(:spin) :current of :total, :percent, eta: :eta"
  )

  res[] <- Inf
  result <- reduce(
    .x = line_coords,
    .init = res,
    .f = function(res, crd){
      pb$tick()
      crd <- crd[[1]]
      r <- dist2Line(p, crd, distfun) # have to live without ID
      k <- r[, 1] < res[, 1]
      res[k, ] <- r[k, ]
      return(res)
    }
  )
  return(result)
}

dist2Line <- function (p, line, distfun = distGeo)
{
  p <- geosphere:::.pointsToMatrix(p)
  if (inherits(line, "SpatialPolygons")) {
    line <- methods::as(line, "SpatialLines")
  }
  if (inherits(line, "SpatialLines")) {
    return(spDistPoint2Line(p, line, distfun))
  }

  line <- geosphere:::.pointsToMatrix(line)
  line1 <- line[-nrow(line), , drop = FALSE]
  line2 <- line[-1, , drop = FALSE]
  seglength <- distfun(line1, line2)

  res <-
    p %>%
      array_branch(1) %>%
      map(
        function(xy){
          crossdist <- abs(dist2gc(line1, line2, xy))
          trackdist1 <- alongTrackDistance(line1, line2, xy)
          trackdist2 <- alongTrackDistance(line2, line1, xy)
          mintrackdist <- pmin(trackdist1, trackdist2)
          maxtrackdist <- pmax(trackdist1, trackdist2)
          crossdist[maxtrackdist >= seglength] <- NA
          nodedist <- distfun(xy, line)
          warnopt = getOption("warn")
          options(warn = -1)
          distmin1 <- min(nodedist, na.rm = TRUE)
          distmin2 <- min(crossdist, na.rm = TRUE)
          options(warn = warnopt)
          if (distmin1 <= distmin2) {
            j <- which.min(nodedist)
            return(c(distmin1, line[j, ]))
          }
          else {
            j <- which.min(crossdist)
            if (trackdist1[j] < trackdist2[j]) {
              bear <- bearing(line1[j, ], line2[j, ])
              pt <- destPoint(line1[j, ], bear, mintrackdist[j])
              return(c(crossdist[j], pt))
            }
            else {
              bear <- bearing(line2[j, ], line1[j, ])
              pt <- destPoint(line2[j, ], bear, mintrackdist[j])
              return(c(crossdist[j], pt))
            }
          }
        }
      ) %>%
      simplify %>%
      matrix(ncol = 3, byrow = TRUE)

  colnames(res) <- c("distance", "lon", "lat")
  return(res)
}


问:
How to use guacenc in guacamole?
I am running guacamole using docker image. I want to record RDP session. I've recorded RDP session, which is in raw format. In guacamole doc there is a utility called guacenc which convert recorded file data into a .m4v video format by using this command.

guacenc /path/to/recording/NAME.

Here I do not know, where I've to run this command.

答: You have to be logged into a terminal session on your server.</p>

Title: How to use guacenc in guacamole?


问:
Julia - Read every 358 lines of a file
I am working on some calculations for my crystals. My file has around 15,750,756 x-y-z coordinates in string format. I want to read the information in every 358 line, but I don't know how to do it.

I only know this code. But It will read every single line instead of every 358 line.

```<code>file = open(trajectory_file_path)
for i in eachline(file)
#What to do here?
    append!(defect_positions,[split(i[4:end])] )
end
end
close(file)
</code>```

答:
I suppose you have in a file test.csv the following lines :

```<code>1 2 3
4 5 6
...
100 101 102
...
</code>```

with for example, more than 358 lines and the three values representing your x-y-z coordinates.

For reading every 358 lines and storing in the array defect_positions you could to the following:

```<code>function read_some_lines(filepath::String)

    defect_positions = Vector{Vector{SubString{String}}}(undef, 0)
    file = open(filepath)
    counter = 0
    for i in eachline(file)
        if (counter%358 == 0)
            push!(defect_positions,split(i))
        end
        counter += 1
    end
    close(file)
    defect_positions
end

read_some_lines("./test.csv")
</code>```

You could want to convert the strings representing your coordinates into Integers or Float64 for instance.

```<code>function read_some_lines(filepath::String)

    defect_positions = Vector{Vector{Int}}(undef, 0)
    file = open(filepath)
    counter = 0
    for i in eachline(file)
        if (counter%358 == 0)
            push!(defect_positions,parse.(Int,split(i)))
        end
        counter += 1
    end
    close(file)
    defect_positions
end

read_some_lines("./test.csv")
</code>```

Title: Julia - Read every 358 lines of a file

Body:
I am working on some calculations for my crystals. My file has around 15,750,756 x-y-z coordinates in string format. I want to read the information in every 358 line, but I don't know how to do it.

I only know this code. But It will read every single line instead of every 358 line.

file = open(trajectory_file_path)
for i in eachline(file)
#What to do here?
    append!(defect_positions,[split(i[4:end])] )
end
end
close(file)

Body:
I suppose you have in a file test.csv the following lines :

1 2 3
4 5 6
...
100 101 102
...

with for example, more than 358 lines and the three values representing your x-y-z coordinates.

For reading every 358 lines and storing in the array defect_positions you could to the following:

function read_some_lines(filepath::String)

    defect_positions = Vector{Vector{SubString{String}}}(undef, 0)
    file = open(filepath)
    counter = 0
    for i in eachline(file)
        if (counter%358 == 0)
            push!(defect_positions,split(i))
        end
        counter += 1
    end
    close(file)
    defect_positions
end

read_some_lines("./test.csv")

You could want to convert the strings representing your coordinates into Integers or Float64 for instance.

function read_some_lines(filepath::String)

    defect_positions = Vector{Vector{Int}}(undef, 0)
    file = open(filepath)
    counter = 0
    for i in eachline(file)
        if (counter%358 == 0)
            push!(defect_positions,parse.(Int,split(i)))
        end
        counter += 1
    end
    close(file)
    defect_positions
end

read_some_lines("./test.csv")


问:
CUDA in C: How to fix Error 11 with cudaMemcpyAsync
I am currently trying to get a simple multi-GPU program running with CUDA.
What it basically does is it copies a large array with some dummy data in chunks to the GPUs, which do some math, and then copy the resulting array back.

I dont get any errors in the output of VS2017, but some error messages I have set up show me that while trying to copy either H2D or D2H.
It tells me that a cudaErrorInvalidValue is occuring.
Also, when using the cudaFree(); function, i get a cudaErrorInvalidDevicePointer error.

The output of the program, the result, is completely wrong. The kernel is, for testing purposes, only setting every value of the output array to a value of 50. The result is a relatively large negative number, always the same no matter what the kernel does.

I have already tried to use a pointer that is not part of a struct, but is defined right before the cudaMalloc, where it is used first. That did not change anything.

This is the function that runs the Kernel:

```<code>void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan)
{
    cudaSetDevice(device);

    cudaStreamCreate(&gpuplan.stream);

    cudaMemcpyAsync(gpuplan.d_data_ptr, h_data, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyHostToDevice, gpuplan.stream); //asynchronous memory copy of the data array h2d

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy H2D on GPU %i: Error %i\n", device, x);
    }

    dummyKernel << <BLOCK_N, THREAD_N, 0, gpuplan.stream >> > (gpuplan.d_data_ptr, gpuplan.d_out_ptr, kernelPlan.ComputationsPerThread, kernelPlan.AdditionalComputationThreadCount); //run kernel

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("no successfull kernel launch\n Kernel Launch Error %i \n", x);
    }
    else {
        printf("kernel ran.\n");
    }

    cudaMemcpyAsync(h_out, gpuplan.d_out_ptr, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyDeviceToHost, gpuplan.stream); //asynchronous memory copy of the output array d2h

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy D2H on GPU %i: Error %i\n", device, x);
    }

    cudaStreamDestroy(gpuplan.stream);
}
</code>```

Then here, how the struct is defined in the "kernel.h":

```<code>#ifndef KERNEL_H
#define KERNEL_H

#include "cuda_runtime.h"

//GPU plan
typedef struct
{
    unsigned int Computations; //computations on this GPU

    unsigned int Repetitions; // amount of kernel repetitions

    unsigned int ComputationsPerRepetition; // amount of computations in every kernel execution
    unsigned int AdditionalComputationRepetitionsCount; // amount of repetitions that need to do one additional computation

    unsigned int DataStartingPoint; // tells the kernel launch at which point in the DATA array this GPU has to start working

    float* d_data_ptr;
    float* d_out_ptr;

    cudaStream_t stream;
} GPUplan;

typedef struct
{
    unsigned int Computations;

    unsigned int ComputationsPerThread; // number of computations every thread of this repetition on this GPU has to do
    unsigned int AdditionalComputationThreadCount; // number of threads in this repetition on this GPU that have to

    unsigned int DataStartingPoint; // tells the kernel launch at which point in the DATA array this repetition has to start working

} KernelPlan;

GPUplan planGPUComputation(int DATA_N, int GPU_N, int device, long long MemoryPerComputation, int dataCounter);

KernelPlan planKernelComputation(int GPUDataStartingPoint, int GPUComputationsPerRepetition, int GPUAdditionalComputationRepetitionsCount, int Repetition, int dataCounter, int THREAD_N, int BLOCK_N);

void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan);

void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan);

void memFree(int device, GPUplan gpuPlan);

__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount);

#endif
</code>```

here the part of code that calls runKernel:

```<code>int GPU_N;
cudaGetDeviceCount(&GPU_N);

const int BLOCK_N = 32;
const int THREAD_N = 1024;

const int DATA_N = 144000;

const int MemoryPerComputation = sizeof(float);

float *h_data;
float *h_out;

h_data = (float *)malloc(MemoryPerComputation * DATA_N);
h_out = (float *)malloc(MemoryPerComputation * DATA_N);

float* sourcePointer;
float* destPointer;

for (int i = 0; i < maxRepetitionCount; i++) // repeat this enough times so that the GPU with the most repetitions will get through all of them
    {
        //malloc
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memAllocation(j, MemoryPerComputation, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        //kernel launch/memcpy
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                sourcePointer = h_data + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;
                destPointer = h_out + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;

                runKernel(j, i, sourcePointer, destPointer, MemoryPerComputation, BLOCK_N, THREAD_N, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memFree(j, plan[j]);
            }
        }
    }
</code>```

I dont think that the kernel itself would be of any importance here since the memcpy error already appears before it is even executed.

The expected output is, that every element of the output array is 50. Instead, every element is -431602080.0

The array is a float array.

EDIT: here is the full code used to reproduce the problem (in addition to kernel.h from above):

```<code>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <stdlib.h>

#include "kernel.h"
#define MAX_GPU_COUNT 32
#define MAX_REP_COUNT 64

__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount) {
    int computations = d_ComputationsPerThread; //computations to be performed in this repetition on this GPU
    const int threadID = blockDim.x * blockIdx.x + threadIdx.x; //thread id within GPU Repetition

    if (threadID > d_AdditionalComputationThreadCount) {
        computations++; //check if thread has to do an additional computation
    }

    for (int i = 0; i < computations; i++) {
        d_out[i * blockDim.x * gridDim.x + threadID] = 50;
    }
}

GPUplan planGPUComputation(int DATA_N, int GPU_N, int device, long long MemoryPerComputation, int dataCounter)
{
    GPUplan plan;
    size_t free, total;

    //computations on GPU #device
    plan.Computations = DATA_N / GPU_N;
    //take into account odd data size for this GPU
    if (DATA_N % GPU_N > device) {
        plan.Computations++;
    }

    plan.DataStartingPoint = dataCounter;

    //get memory information
    cudaSetDevice(device);
    cudaMemGetInfo(&free, &total);

    //calculate Repetitions on this GPU #device
    plan.Repetitions = ((plan.Computations * MemoryPerComputation / free) + 1);
    printf("Repetitions: %i\n", plan.Repetitions);

    if (plan.Repetitions > MAX_REP_COUNT) {
        printf("Repetition count larger than MAX_REP_COUNT %i\n\n", MAX_REP_COUNT);
    }

    //calculate Computations per Repetition
    plan.ComputationsPerRepetition = plan.Computations / plan.Repetitions;

    //calculate how many Repetitions have to do an additional Computation
    plan.AdditionalComputationRepetitionsCount = plan.Computations % plan.Repetitions;

    return plan;
}

KernelPlan planKernelComputation(int GPUDataStartingPoint, int GPUComputationsPerRepetition, int GPUAdditionalComputationRepetitionsCount, int Repetition, int dataCounter, int THREAD_N, int BLOCK_N)
{
    KernelPlan plan;
    //calculate total Calculations in this Repetition
    plan.Computations = GPUComputationsPerRepetition;

    if (GPUAdditionalComputationRepetitionsCount > Repetition) {
        plan.Computations++;
    }

    plan.ComputationsPerThread = plan.Computations / (THREAD_N * BLOCK_N); // Computations every thread has to do (+- 1)
    plan.AdditionalComputationThreadCount = plan.Computations % (THREAD_N * BLOCK_N); // how many threads have to do +1 calculation

    plan.DataStartingPoint = GPUDataStartingPoint + dataCounter;

    return plan;
}

void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan)
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Error Selecting device %i: Error %i\n", device, x);
    }
    cudaMalloc((void**)&(gpuPlan.d_data_ptr), MemoryPerComputation * kernelPlan.Computations); // device data array memory allocation
    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Malloc 1 on GPU %i: Error %i\n", device, x);
    }

    cudaMalloc((void**)&(gpuPlan.d_out_ptr), MemoryPerComputation * kernelPlan.Computations); // device output array memory allocation
    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Malloc 2 on GPU %i: Error %i\n", device, x);
    }
}

void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan)
{
    cudaSetDevice(device);

    cudaStreamCreate(&gpuplan.stream);

    cudaMemcpyAsync(gpuplan.d_data_ptr, h_data, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyHostToDevice, gpuplan.stream); //asynchronous memory copy of the data array h2d

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy H2D on GPU %i: Error %i\n", device, x);
    }

    dummyKernel << <BLOCK_N, THREAD_N, 0, gpuplan.stream >> > (gpuplan.d_data_ptr, gpuplan.d_out_ptr, kernelPlan.ComputationsPerThread, kernelPlan.AdditionalComputationThreadCount); //run kernel

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("no successfull kernel launch\n Kernel Launch Error %i \n", x);
    }
    else {
        printf("kernel ran.\n");
    }

    cudaMemcpyAsync(h_out, gpuplan.d_out_ptr, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyDeviceToHost, gpuplan.stream); //asynchronous memory copy of the output array d2h

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy D2H on GPU %i: Error %i\n", device, x);
    }

    cudaStreamDestroy(gpuplan.stream);
}

void memFree(int device, GPUplan gpuPlan)
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaFree(gpuPlan.d_data_ptr);
    cudaFree(gpuPlan.d_out_ptr);

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memfree on GPU %i: Error %i\n", device, x);
    }
    else {
        printf("memory freed.\n");
    }
    //17 = cudaErrorInvalidDevicePointer
}

int main()
{
    //get device count
    int GPU_N;
    cudaGetDeviceCount(&GPU_N);
    //adjust for device count larger than MAX_GPU_COUNT
    if (GPU_N > MAX_GPU_COUNT)
    {
        GPU_N = MAX_GPU_COUNT;
    }

    printf("GPU count: %i\n", GPU_N);

    //definitions for running the program
    const int BLOCK_N = 32;
    const int THREAD_N = 1024;

    const int DATA_N = 144000;

    const int MemoryPerComputation = sizeof(float);

    ///////////////////////////////////////////////////////////
    //Subdividing input data across GPUs
    //////////////////////////////////////////////

    //GPUplan
    GPUplan plan[MAX_GPU_COUNT];
    int dataCounter = 0;

    for (int i = 0; i < GPU_N; i++)
    {
        plan[i] = planGPUComputation(DATA_N, GPU_N, i, MemoryPerComputation, dataCounter);
        dataCounter += plan[i].Computations;
    }

    //KernelPlan
    KernelPlan kernelPlan[MAX_GPU_COUNT*MAX_REP_COUNT];

    for (int i = 0; i < GPU_N; i++)
    {
        int GPURepetitions = plan[i].Repetitions;
        dataCounter = plan[i].DataStartingPoint;

        for (int j = 0; j < GPURepetitions; j++)
        {
            kernelPlan[i*MAX_REP_COUNT + j] = planKernelComputation(plan[i].DataStartingPoint, plan[i].ComputationsPerRepetition, plan[i].AdditionalComputationRepetitionsCount, j, dataCounter, THREAD_N, BLOCK_N);

            dataCounter += kernelPlan[i*MAX_REP_COUNT + j].Computations;
        }
    }

    float *h_data;
    float *h_out;

    h_data = (float *)malloc(MemoryPerComputation * DATA_N);
    h_out = (float *)malloc(MemoryPerComputation * DATA_N);

    //generate some input data
    for (int i = 0; i < DATA_N; i++) {
        h_data[i] = 2 * i;
    }

    //get highest repetition count
    int maxRepetitionCount = 0;
    for (int i = 0; i < GPU_N; i++) {
        if (plan[i].Repetitions > maxRepetitionCount) {
            maxRepetitionCount = plan[i].Repetitions;
        }
    }

    printf("maxRepetitionCount: %i\n\n", maxRepetitionCount);

    float* sourcePointer;
    float* destPointer;

    for (int i = 0; i < maxRepetitionCount; i++) // repeat this enough times so that the GPU with the most repetitions will get through all of them
    {
        //malloc
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memAllocation(j, MemoryPerComputation, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        //kernel launch/memcpy
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                sourcePointer = h_data + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;
                destPointer = h_out + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;

                runKernel(j, i, sourcePointer, destPointer, MemoryPerComputation, BLOCK_N, THREAD_N, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memFree(j, plan[j]);
            }
        }
    }

    //printing expected results and results
    for (int i = 0; i < 50; i++)
    {
        printf("%f\t", h_data[i]);
        printf("%f\n", h_out[i]);
    }

    free(h_data);
    free(h_out);

    getchar();

    return 0;
}
</code>```

答:
The first problem has nothing to do with CUDA, actually.  When you pass a struct by-value to a function in C or C++, a copy of that struct is made for use by the function.  Modifications to that struct in the function have no effect on the original struct in the calling environment.  This is affecting you in your memAllocation function:

```<code>void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan)
                                                                 ^^^^^^^
                                                                 passed by value
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Error Selecting device %i: Error %i\n", device, x);
    }
    cudaMalloc((void**)&(gpuPlan.d_data_ptr), MemoryPerComputation * kernelPlan.Computations); // device data array memory allocation
                         ^^^^^^^^^^^^^^^^^^
                         modifying the copy, not the original
</code>```

This is fairly easily fixable by passing the gpuPlan struct by reference rather than by value.  Modify both the prototype in the kernel.h header file, as well as the definition:

```<code>void memAllocation(int device, int MemoryPerComputation, GPUplan &gpuPlan, KernelPlan kernelPlan)
                                                                 ^
</code>```

with that change, the struct is passed by reference, and modifications (such as the setting of the allocated pointers) will show up in the calling environment.  This is the proximal reason for the invalid argument report on the cudaMemcpy operations. The pointers you were passing were unallocated, because your allocations were done on the pointer copies, not the originals.

After that change your code may appear to be running correctly. At least when I run it no errors are displayed and the outputs appear to be all set to 50.

However there are still problems with this code.  If you run your code with cuda-memcheck (or turn on the memory checker functionality in nsight VSE) you should see errors associated with this line of code, which is indexing out of bounds:

```<code>__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount) {
...
    d_out[i * blockDim.x * gridDim.x + threadID] = 50; //indexing out of bounds
</code>```

I'm not going to try to sort that out for you.  It seems evident to me that your for-loop, coupled with the way you are calculating the index, is going beyond the end of the array.  You can follow the methodology discussed here if needed.

Body:
I am currently trying to get a simple multi-GPU program running with CUDA.
What it basically does is it copies a large array with some dummy data in chunks to the GPUs, which do some math, and then copy the resulting array back.

I dont get any errors in the output of VS2017, but some error messages I have set up show me that while trying to copy either H2D or D2H.
It tells me that a cudaErrorInvalidValue is occuring.
Also, when using the cudaFree(); function, i get a cudaErrorInvalidDevicePointer error.

The output of the program, the result, is completely wrong. The kernel is, for testing purposes, only setting every value of the output array to a value of 50. The result is a relatively large negative number, always the same no matter what the kernel does.

I have already tried to use a pointer that is not part of a struct, but is defined right before the cudaMalloc, where it is used first. That did not change anything.

This is the function that runs the Kernel:

void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan)
{
    cudaSetDevice(device);

    cudaStreamCreate(&gpuplan.stream);

    cudaMemcpyAsync(gpuplan.d_data_ptr, h_data, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyHostToDevice, gpuplan.stream); //asynchronous memory copy of the data array h2d

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy H2D on GPU %i: Error %i\n", device, x);
    }

    dummyKernel << <BLOCK_N, THREAD_N, 0, gpuplan.stream >> > (gpuplan.d_data_ptr, gpuplan.d_out_ptr, kernelPlan.ComputationsPerThread, kernelPlan.AdditionalComputationThreadCount); //run kernel

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("no successfull kernel launch\n Kernel Launch Error %i \n", x);
    }
    else {
        printf("kernel ran.\n");
    }

    cudaMemcpyAsync(h_out, gpuplan.d_out_ptr, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyDeviceToHost, gpuplan.stream); //asynchronous memory copy of the output array d2h

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy D2H on GPU %i: Error %i\n", device, x);
    }

    cudaStreamDestroy(gpuplan.stream);
}

Then here, how the struct is defined in the "kernel.h":

#ifndef KERNEL_H
#define KERNEL_H

#include "cuda_runtime.h"

//GPU plan
typedef struct
{
    unsigned int Computations; //computations on this GPU

    unsigned int Repetitions; // amount of kernel repetitions

    unsigned int ComputationsPerRepetition; // amount of computations in every kernel execution
    unsigned int AdditionalComputationRepetitionsCount; // amount of repetitions that need to do one additional computation

    unsigned int DataStartingPoint; // tells the kernel launch at which point in the DATA array this GPU has to start working

    float* d_data_ptr;
    float* d_out_ptr;

    cudaStream_t stream;
} GPUplan;

typedef struct
{
    unsigned int Computations;

    unsigned int ComputationsPerThread; // number of computations every thread of this repetition on this GPU has to do
    unsigned int AdditionalComputationThreadCount; // number of threads in this repetition on this GPU that have to

    unsigned int DataStartingPoint; // tells the kernel launch at which point in the DATA array this repetition has to start working

} KernelPlan;

GPUplan planGPUComputation(int DATA_N, int GPU_N, int device, long long MemoryPerComputation, int dataCounter);

KernelPlan planKernelComputation(int GPUDataStartingPoint, int GPUComputationsPerRepetition, int GPUAdditionalComputationRepetitionsCount, int Repetition, int dataCounter, int THREAD_N, int BLOCK_N);

void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan);

void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan);

void memFree(int device, GPUplan gpuPlan);

__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount);

#endif

here the part of code that calls runKernel:

int GPU_N;
cudaGetDeviceCount(&GPU_N);

const int BLOCK_N = 32;
const int THREAD_N = 1024;

const int DATA_N = 144000;

const int MemoryPerComputation = sizeof(float);

float *h_data;
float *h_out;

h_data = (float *)malloc(MemoryPerComputation * DATA_N);
h_out = (float *)malloc(MemoryPerComputation * DATA_N);

float* sourcePointer;
float* destPointer;

for (int i = 0; i < maxRepetitionCount; i++) // repeat this enough times so that the GPU with the most repetitions will get through all of them
    {
        //malloc
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memAllocation(j, MemoryPerComputation, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        //kernel launch/memcpy
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                sourcePointer = h_data + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;
                destPointer = h_out + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;

                runKernel(j, i, sourcePointer, destPointer, MemoryPerComputation, BLOCK_N, THREAD_N, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memFree(j, plan[j]);
            }
        }
    }

I dont think that the kernel itself would be of any importance here since the memcpy error already appears before it is even executed.

The expected output is, that every element of the output array is 50. Instead, every element is -431602080.0

The array is a float array.

EDIT: here is the full code used to reproduce the problem (in addition to kernel.h from above):

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <stdlib.h>

#include "kernel.h"
#define MAX_GPU_COUNT 32
#define MAX_REP_COUNT 64

__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount) {
    int computations = d_ComputationsPerThread; //computations to be performed in this repetition on this GPU
    const int threadID = blockDim.x * blockIdx.x + threadIdx.x; //thread id within GPU Repetition

    if (threadID > d_AdditionalComputationThreadCount) {
        computations++; //check if thread has to do an additional computation
    }

    for (int i = 0; i < computations; i++) {
        d_out[i * blockDim.x * gridDim.x + threadID] = 50;
    }
}

GPUplan planGPUComputation(int DATA_N, int GPU_N, int device, long long MemoryPerComputation, int dataCounter)
{
    GPUplan plan;
    size_t free, total;

    //computations on GPU #device
    plan.Computations = DATA_N / GPU_N;
    //take into account odd data size for this GPU
    if (DATA_N % GPU_N > device) {
        plan.Computations++;
    }

    plan.DataStartingPoint = dataCounter;

    //get memory information
    cudaSetDevice(device);
    cudaMemGetInfo(&free, &total);

    //calculate Repetitions on this GPU #device
    plan.Repetitions = ((plan.Computations * MemoryPerComputation / free) + 1);
    printf("Repetitions: %i\n", plan.Repetitions);

    if (plan.Repetitions > MAX_REP_COUNT) {
        printf("Repetition count larger than MAX_REP_COUNT %i\n\n", MAX_REP_COUNT);
    }

    //calculate Computations per Repetition
    plan.ComputationsPerRepetition = plan.Computations / plan.Repetitions;

    //calculate how many Repetitions have to do an additional Computation
    plan.AdditionalComputationRepetitionsCount = plan.Computations % plan.Repetitions;

    return plan;
}

KernelPlan planKernelComputation(int GPUDataStartingPoint, int GPUComputationsPerRepetition, int GPUAdditionalComputationRepetitionsCount, int Repetition, int dataCounter, int THREAD_N, int BLOCK_N)
{
    KernelPlan plan;
    //calculate total Calculations in this Repetition
    plan.Computations = GPUComputationsPerRepetition;

    if (GPUAdditionalComputationRepetitionsCount > Repetition) {
        plan.Computations++;
    }

    plan.ComputationsPerThread = plan.Computations / (THREAD_N * BLOCK_N); // Computations every thread has to do (+- 1)
    plan.AdditionalComputationThreadCount = plan.Computations % (THREAD_N * BLOCK_N); // how many threads have to do +1 calculation

    plan.DataStartingPoint = GPUDataStartingPoint + dataCounter;

    return plan;
}

void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan)
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Error Selecting device %i: Error %i\n", device, x);
    }
    cudaMalloc((void**)&(gpuPlan.d_data_ptr), MemoryPerComputation * kernelPlan.Computations); // device data array memory allocation
    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Malloc 1 on GPU %i: Error %i\n", device, x);
    }

    cudaMalloc((void**)&(gpuPlan.d_out_ptr), MemoryPerComputation * kernelPlan.Computations); // device output array memory allocation
    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Malloc 2 on GPU %i: Error %i\n", device, x);
    }
}

void runKernel(int device, int Repetition, float* h_data, float* h_out, int MemoryPerComputation, int BLOCK_N, int THREAD_N, GPUplan gpuplan, KernelPlan kernelPlan)
{
    cudaSetDevice(device);

    cudaStreamCreate(&gpuplan.stream);

    cudaMemcpyAsync(gpuplan.d_data_ptr, h_data, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyHostToDevice, gpuplan.stream); //asynchronous memory copy of the data array h2d

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy H2D on GPU %i: Error %i\n", device, x);
    }

    dummyKernel << <BLOCK_N, THREAD_N, 0, gpuplan.stream >> > (gpuplan.d_data_ptr, gpuplan.d_out_ptr, kernelPlan.ComputationsPerThread, kernelPlan.AdditionalComputationThreadCount); //run kernel

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("no successfull kernel launch\n Kernel Launch Error %i \n", x);
    }
    else {
        printf("kernel ran.\n");
    }

    cudaMemcpyAsync(h_out, gpuplan.d_out_ptr, kernelPlan.Computations * MemoryPerComputation, cudaMemcpyDeviceToHost, gpuplan.stream); //asynchronous memory copy of the output array d2h

    x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memcpy D2H on GPU %i: Error %i\n", device, x);
    }

    cudaStreamDestroy(gpuplan.stream);
}

void memFree(int device, GPUplan gpuPlan)
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaFree(gpuPlan.d_data_ptr);
    cudaFree(gpuPlan.d_out_ptr);

    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Memfree on GPU %i: Error %i\n", device, x);
    }
    else {
        printf("memory freed.\n");
    }
    //17 = cudaErrorInvalidDevicePointer
}

int main()
{
    //get device count
    int GPU_N;
    cudaGetDeviceCount(&GPU_N);
    //adjust for device count larger than MAX_GPU_COUNT
    if (GPU_N > MAX_GPU_COUNT)
    {
        GPU_N = MAX_GPU_COUNT;
    }

    printf("GPU count: %i\n", GPU_N);

    //definitions for running the program
    const int BLOCK_N = 32;
    const int THREAD_N = 1024;

    const int DATA_N = 144000;

    const int MemoryPerComputation = sizeof(float);

    ///////////////////////////////////////////////////////////
    //Subdividing input data across GPUs
    //////////////////////////////////////////////

    //GPUplan
    GPUplan plan[MAX_GPU_COUNT];
    int dataCounter = 0;

    for (int i = 0; i < GPU_N; i++)
    {
        plan[i] = planGPUComputation(DATA_N, GPU_N, i, MemoryPerComputation, dataCounter);
        dataCounter += plan[i].Computations;
    }

    //KernelPlan
    KernelPlan kernelPlan[MAX_GPU_COUNT*MAX_REP_COUNT];

    for (int i = 0; i < GPU_N; i++)
    {
        int GPURepetitions = plan[i].Repetitions;
        dataCounter = plan[i].DataStartingPoint;

        for (int j = 0; j < GPURepetitions; j++)
        {
            kernelPlan[i*MAX_REP_COUNT + j] = planKernelComputation(plan[i].DataStartingPoint, plan[i].ComputationsPerRepetition, plan[i].AdditionalComputationRepetitionsCount, j, dataCounter, THREAD_N, BLOCK_N);

            dataCounter += kernelPlan[i*MAX_REP_COUNT + j].Computations;
        }
    }

    float *h_data;
    float *h_out;

    h_data = (float *)malloc(MemoryPerComputation * DATA_N);
    h_out = (float *)malloc(MemoryPerComputation * DATA_N);

    //generate some input data
    for (int i = 0; i < DATA_N; i++) {
        h_data[i] = 2 * i;
    }

    //get highest repetition count
    int maxRepetitionCount = 0;
    for (int i = 0; i < GPU_N; i++) {
        if (plan[i].Repetitions > maxRepetitionCount) {
            maxRepetitionCount = plan[i].Repetitions;
        }
    }

    printf("maxRepetitionCount: %i\n\n", maxRepetitionCount);

    float* sourcePointer;
    float* destPointer;

    for (int i = 0; i < maxRepetitionCount; i++) // repeat this enough times so that the GPU with the most repetitions will get through all of them
    {
        //malloc
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memAllocation(j, MemoryPerComputation, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        //kernel launch/memcpy
        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                sourcePointer = h_data + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;
                destPointer = h_out + kernelPlan[j*MAX_REP_COUNT + i].DataStartingPoint;

                runKernel(j, i, sourcePointer, destPointer, MemoryPerComputation, BLOCK_N, THREAD_N, plan[j], kernelPlan[j*MAX_REP_COUNT + i]);
            }
        }

        for (int j = 0; j < GPU_N; j++)
        {
            if (plan[j].Repetitions >= i) // when this GPU has to do at least i repetitions
            {
                memFree(j, plan[j]);
            }
        }
    }

    //printing expected results and results
    for (int i = 0; i < 50; i++)
    {
        printf("%f\t", h_data[i]);
        printf("%f\n", h_out[i]);
    }

    free(h_data);
    free(h_out);

    getchar();

    return 0;
}

Body:
The first problem has nothing to do with CUDA, actually.  When you pass a struct by-value to a function in C or C++, a copy of that struct is made for use by the function.  Modifications to that struct in the function have no effect on the original struct in the calling environment.  This is affecting you in your memAllocation function:

void memAllocation(int device, int MemoryPerComputation, GPUplan gpuPlan, KernelPlan kernelPlan)
                                                                 ^^^^^^^
                                                                 passed by value
{
    cudaSetDevice(device); //select device to allocate memory on
    cudaError_t x = cudaGetLastError();
    if (x != cudaSuccess) {
        printf("Error Selecting device %i: Error %i\n", device, x);
    }
    cudaMalloc((void**)&(gpuPlan.d_data_ptr), MemoryPerComputation * kernelPlan.Computations); // device data array memory allocation
                         ^^^^^^^^^^^^^^^^^^
                         modifying the copy, not the original

This is fairly easily fixable by passing the gpuPlan struct by reference rather than by value.  Modify both the prototype in the kernel.h header file, as well as the definition:

void memAllocation(int device, int MemoryPerComputation, GPUplan &gpuPlan, KernelPlan kernelPlan)
                                                                 ^

with that change, the struct is passed by reference, and modifications (such as the setting of the allocated pointers) will show up in the calling environment.  This is the proximal reason for the invalid argument report on the cudaMemcpy operations. The pointers you were passing were unallocated, because your allocations were done on the pointer copies, not the originals.

After that change your code may appear to be running correctly. At least when I run it no errors are displayed and the outputs appear to be all set to 50.

However there are still problems with this code.  If you run your code with cuda-memcheck (or turn on the memory checker functionality in nsight VSE) you should see errors associated with this line of code, which is indexing out of bounds:

__global__ void dummyKernel(float *d_data, float *d_out, int d_ComputationsPerThread, int d_AdditionalComputationThreadCount) {
...
    d_out[i * blockDim.x * gridDim.x + threadID] = 50; //indexing out of bounds

I'm not going to try to sort that out for you.  It seems evident to me that your for-loop, coupled with the way you are calculating the index, is going beyond the end of the array.  You can follow the methodology discussed here if needed.


问:
Managed dict of list not updated in multiprocessing when using += operator
Consider the following python code:

from multiprocessing import Process, Manager

class MyClass():
    def __init__(self, dic1, dic2):
        self.dic1 = Manager().dict(dic1) # Create a managed dictionary
        self.dic2 = Manager().dict(dic2) # Create a managed dictionary
        process1 = Process(target=self.dictSumOverloaded, args=())
        process2 = Process(target=self.dictSumElementWise, args=())

        process1.start()
        process1.join()

        process2.start()
        process2.join()

    def dictSumOverloaded(self):
        self.dic1['1'][0] += 1 # dic1 is not updated

    def dictSumElementWise(self):
        a = self.dic2['1']
        self.dic2['1'] = [a[0]+1, a[1], a[2]] # dic2 is updated

def main():
    dic1 = {'1': [1, 0, 0]}
    dic2 = {'1': [1, 0, 0]}

    result = MyClass(dic1, dic2)
    print(result.dic1) # Failed
    print(result.dic2) # Success

    # Bypass multiprocessing environment
    dic3 = {'1': [1, 0, 0]}
    dic3['1'][0]+=1
    print(dic3) # Success

if __name__ == '__main__':
    main()
```

In this example, I create a managed dict containing a list as an attribute of MyClass. The goal is to increment some of the elements of this list in a multiprocessing environment, but some methods do not effectively modify the list.

Method 1: dictSumOverloaded

The overloaded operator += is used to increment an element of the list by 1 but the result does not persist. The dict is not updated.

Method 2: dictSumElementWise

This function creates a new list element wise, based on the old list and the values to add. Then the new list is assigned to the dict key. The dict is successfully modified.

Sanity check: outside the multiprocessing environment

dic3 is modified as expected when using += outside the multiprocessing environment.

Questions:

1) Why is += not modifying the list element in the multiprocessing environment?

2) Using the element wise method to update the list works but is cumbersome, any suggestion on making it cleaner/faster?

答:
I believe the problem you are encountering is related to detection of a change in the dictionary dic1 by the anonymous Manager object that you create it with.

Changing the list itself with += operator does not change the reference to the list - it is the same list, just an element of it has changed (namely 0-th element of a list stored in the thread-safe dictionary dic1 under the key '1').

With dic2 the situation is different. With the following line:

```<code>self.dic2['1'] = [a[0]+1, a[1], a[2]]
</code>```

You effectively update the value stored under the key '1'. The assigned value is a completely new list. It is made of elements of the list stored as the previous value under the same key but it is nevertheless a different list.

Such a change is detected by the Manager object and the reference in the process in which you check the value of dic2 is seamlessly updated so that you could read the correct value.

The main point here is the following:

the thread-safe collection (dict) does not propagate any changes to other processes (or threads) if there are no changes to keys, or values, or both. List is a reference type so the value (i.e. reference) does not change even if the list values change.

Body:
Consider the following python code:

from multiprocessing import Process, Manager

class MyClass():
    def __init__(self, dic1, dic2):
        self.dic1 = Manager().dict(dic1) # Create a managed dictionary
        self.dic2 = Manager().dict(dic2) # Create a managed dictionary
        process1 = Process(target=self.dictSumOverloaded, args=())
        process2 = Process(target=self.dictSumElementWise, args=())

        process1.start()
        process1.join()

        process2.start()
        process2.join()

    def dictSumOverloaded(self):
        self.dic1['1'][0] += 1 # dic1 is not updated

    def dictSumElementWise(self):
        a = self.dic2['1']
        self.dic2['1'] = [a[0]+1, a[1], a[2]] # dic2 is updated

def main():
    dic1 = {'1': [1, 0, 0]}
    dic2 = {'1': [1, 0, 0]}

    result = MyClass(dic1, dic2)
    print(result.dic1) # Failed
    print(result.dic2) # Success

    # Bypass multiprocessing environment
    dic3 = {'1': [1, 0, 0]}
    dic3['1'][0]+=1
    print(dic3) # Success

if __name__ == '__main__':
    main()

In this example, I create a managed dict containing a list as an attribute of MyClass. The goal is to increment some of the elements of this list in a multiprocessing environment, but some methods do not effectively modify the list.

Method 1: dictSumOverloaded

The overloaded operator += is used to increment an element of the list by 1 but the result does not persist. The dict is not updated.

Method 2: dictSumElementWise

This function creates a new list element wise, based on the old list and the values to add. Then the new list is assigned to the dict key. The dict is successfully modified.

Sanity check: outside the multiprocessing environment

dic3 is modified as expected when using += outside the multiprocessing environment.

Questions:

1) Why is += not modifying the list element in the multiprocessing environment?

2) Using the element wise method to update the list works but is cumbersome, any suggestion on making it cleaner/faster?

Body:
I believe the problem you are encountering is related to detection of a change in the dictionary dic1 by the anonymous Manager object that you create it with.

Changing the list itself with += operator does not change the reference to the list - it is the same list, just an element of it has changed (namely 0-th element of a list stored in the thread-safe dictionary dic1 under the key '1').

With dic2 the situation is different. With the following line:

self.dic2['1'] = [a[0]+1, a[1], a[2]]

You effectively update the value stored under the key '1'. The assigned value is a completely new list. It is made of elements of the list stored as the previous value under the same key but it is nevertheless a different list.

Such a change is detected by the Manager object and the reference in the process in which you check the value of dic2 is seamlessly updated so that you could read the correct value.

The main point here is the following:

the thread-safe collection (dict) does not propagate any changes to other processes (or threads) if there are no changes to keys, or values, or both. List is a reference type so the value (i.e. reference) does not change even if the list values change.


问:
How get value from yaml file based on method param in spring?
I work with yaml and spring boot and I will make a method which will be validate my field.

If field value non null I have to return this value.

If field value null I have to load default value from yaml file based on fieldName.

My method example:

```<code>@PropertySource("classpath:defaultValue.yml")
public final class ValidateAttributeValue {

    public static String validateAttributeValue(String attributeName, String attributeValue){
        if (nonNull(attributeValue)){
            return attributeValue;
        }
        //here I have to return default value from file based on attributeName
    }
</code>```

yaml file:

```<code>values:
  field: defaultValue
  field1: defaultValue1
  field2: defaultValue2
  field3: defaultValue3
</code>```

How can it be implemented in Spring boot + yaml?

答:
You can use YamlPropertiesFactoryBean to convert YAML to PropertySource.

```<code>public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }

    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        } catch (IllegalStateException e) {
            // for ignoreResourceNotFound
            Throwable cause = e.getCause();
            if (cause instanceof FileNotFoundException)
                throw (FileNotFoundException) e.getCause();
            throw e;
        }
    }
}
</code>```

And then use it like:

```<code>@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:blog.yaml")
public class YamlPropertysourceApplication {
</code>```

You will find the whole description here:

https://mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files/

Body:
I work with yaml and spring boot and I will make a method which will be validate my field.

If field value non null I have to return this value.

If field value null I have to load default value from yaml file based on fieldName.

My method example:

@PropertySource("classpath:defaultValue.yml")
public final class ValidateAttributeValue {

    public static String validateAttributeValue(String attributeName, String attributeValue){
        if (nonNull(attributeValue)){
            return attributeValue;
        }
        //here I have to return default value from file based on attributeName
    }

yaml file:

values:
  field: defaultValue
  field1: defaultValue1
  field2: defaultValue2
  field3: defaultValue3

How can it be implemented in Spring boot + yaml?

Body:
You can use YamlPropertiesFactoryBean to convert YAML to PropertySource.

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        Properties propertiesFromYaml = loadYamlIntoProperties(resource);
        String sourceName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(sourceName, propertiesFromYaml);
    }

    private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
        try {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return factory.getObject();
        } catch (IllegalStateException e) {
            // for ignoreResourceNotFound
            Throwable cause = e.getCause();
            if (cause instanceof FileNotFoundException)
                throw (FileNotFoundException) e.getCause();
            throw e;
        }
    }
}

And then use it like:

@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:blog.yaml")
public class YamlPropertysourceApplication {

You will find the whole description here:

https://mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files/


问:
Getting properties of keys in Javascript
I have a key/value array that I defined by doing something similar to:

```<code>var arr;

function assign(iSize, jSize)
{
    arr = {};

    for (var i = 0; i < iSize; i++) {
        for (var j = 0; j < jSize; j++) {
            var pt = new Point(i, j);
            arr[pt] = [1, 2, 3];
        }
    }
}
</code>```

Where my Point function is

```<code>function Point(x, y) {
    this.x = x;
    this.y = y;
}
</code>```

and now I would like to iterate through all the values of the array but I also need to know the keys as well. I've tried

```<code>function iterate() {
    for(var e in arr) {
        console.log(e.x);
    }
}
</code>```

but it just prints out undefined. Also, if I try

```<code>function iterate() {
    console.log(Object.keys(arr));
}
</code>```

I just get [object Object] as output.

I've tried printing out the Point at the moment of creation and I can access the x and y values just fine.

As a side note, in my actual implementation I'm not just assigning the array [1, 2, 3] to each index of my array. I am assigning an array generated by another function that has nothing to do with accessing the keys in arr

答:
Your main problem it's arr[pt] = [1, 2, 3];. When you use var pt = new Point(i, j);
result of new Point(i, j) it object {x:i, y:j}

When you try to use object as another object's key (arr[pt] = [1, 2, 3];) engine understand it like arr[pt.toString()] because typeof pt === 'object'

just use another key in arr[pt]

If you really need to use object as a key you can write your own toString for Point. Something like:

```<code>Point.prototype.toString = function pointToString() {
  var ret = JSON.stringify(this);
  return ret;
}
</code>```

And then use it

```<code>function iterate(){
    for(var e in arr){
        console.log(JSON.parse(e).x);
    }
}
</code>```

Body:
I have a key/value array that I defined by doing something similar to:

var arr;

function assign(iSize, jSize)
{
    arr = {};

    for (var i = 0; i < iSize; i++) {
        for (var j = 0; j < jSize; j++) {
            var pt = new Point(i, j);
            arr[pt] = [1, 2, 3];
        }
    }
}

Where my Point function is

function Point(x, y) {
    this.x = x;
    this.y = y;
}

and now I would like to iterate through all the values of the array but I also need to know the keys as well. I've tried

function iterate() {
    for(var e in arr) {
        console.log(e.x);
    }
}

but it just prints out undefined. Also, if I try

function iterate() {
    console.log(Object.keys(arr));
}

I just get [object Object] as output.

I've tried printing out the Point at the moment of creation and I can access the x and y values just fine.

As a side note, in my actual implementation I'm not just assigning the array [1, 2, 3] to each index of my array. I am assigning an array generated by another function that has nothing to do with accessing the keys in arr

Body:
Your main problem it's arr[pt] = [1, 2, 3];. When you use var pt = new Point(i, j);
result of new Point(i, j) it object {x:i, y:j}

When you try to use object as another object's key (arr[pt] = [1, 2, 3];) engine understand it like arr[pt.toString()] because typeof pt === 'object'

just use another key in arr[pt]

If you really need to use object as a key you can write your own toString for Point. Something like:

Point.prototype.toString = function pointToString() {
  var ret = JSON.stringify(this);
  return ret;
}

And then use it

function iterate(){
    for(var e in arr){
        console.log(JSON.parse(e).x);
    }
}


问:
How to clone an Object by copy ByteArrayOutputStream into ByteArray, then call it by ByteArrayInputStream?
I try to clone an Object by 1) shoving it into a ByteArrayOutputStream 2) assigning the stream to a byte array 3) reading the byte array by ByteArrayInputStream. However, this won't work as I can not assign the OutputStream to the byte array, the line will just not execute.

Apporoach is based Java Serializable Object to Byte Array

```<code>public Bank clone() {
        Bank objektKopie = null;
        byte[] byteKopie = null;
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = null;
        try {
            bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(this);
            oo.flush() ;
            byteKopie = bo.toByteArray(); // THIS WILL NOT HAPPEN
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
               bo.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
        ByteArrayInputStream bi = new ByteArrayInputStream(byteKopie); // byteKopie IS STILL NULL
        ObjectInputStream oi = null;
        try {
            oi = new ObjectInputStream(bi);
            objektKopie = (Bank) oi.readObject();
        } catch (Exception e) { System.out.println(e.getMessage()); }
        return objektKopie;
    }
</code>```

答: if dependencies are okay, GSON can do this fairly easily</p>

Body:
I try to clone an Object by 1) shoving it into a ByteArrayOutputStream 2) assigning the stream to a byte array 3) reading the byte array by ByteArrayInputStream. However, this won't work as I can not assign the OutputStream to the byte array, the line will just not execute.

Apporoach is based Java Serializable Object to Byte Array

public Bank clone() {
        Bank objektKopie = null;
        byte[] byteKopie = null;
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = null;
        try {
            bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(this);
            oo.flush() ;
            byteKopie = bo.toByteArray(); // THIS WILL NOT HAPPEN
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
               bo.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
        ByteArrayInputStream bi = new ByteArrayInputStream(byteKopie); // byteKopie IS STILL NULL
        ObjectInputStream oi = null;
        try {
            oi = new ObjectInputStream(bi);
            objektKopie = (Bank) oi.readObject();
        } catch (Exception e) { System.out.println(e.getMessage()); }
        return objektKopie;
    }


问:
Highlighting missing unique pairs when compared to master list - Excel
On Sheet 1, I have a master list of data, with corresponding attributes. Some data has more than one attribute, some has only one, and there is a possibility of blanks. Attributes can be repeated when assigned to a different name.

I've posted some example data below, so we can all talk about the same cells/names etc.

On Sheet 2, there is much more freeform data input/analysis going on. Users are able to select a 'Name' from a dropdown menu using Data Validation, and are then able to select from the available attributes corresponding to that name, again using a dropdown menu. Names and attributes can appear in any order on Sheet 2.

It is important that all pairings are considered in the second worksheet.

Is it possible to use conditional formatting to highlight the 'Name' field (on Sheet 2) until at least one row exists with all possible pairings? In the example below, you can see that we have forgotten to put any info relating to the fact that Sally is Happy, and consequently 'Sally' has been highlighted to draw attention to the fact that there is some missing information.

Current thoughts:
I already have a list of the attributes that match the corresponding name- this is what drives the dropdown menu on Sheet 2, and is generated in a background sheet when a name is picked on Sheet 2. I can count the non-blank cells in this range to find out the total number of pairs that are required.

I would like to then count the number of non-duplicate attributes that are on rows that have the same Name as the current row, and compare this value.

I'm expecting this to get into the realms of array formulae, but may be wrong...
I'm also expecting array formulae to not work directly with conditional formatting, and to require the use of a 'helper column' to drive the formatting. Let me know if this is incorrect?

Something along the lines of the below (formatted as pseudo-code for readability, but this should be read as a high level description, not actual code)

```<code>{Count the 1s in the array(AND(
'Check if it's a name match'
If($D$1:$D$10=[$ACurrent],[set flag to 1],[set flag to 0])
'Check if it's a unique value'
[somehow check array values set at 1 to see if there is a duplicate value in column E, and then set the array value to zero if so])
}
</code>```

Does this approach make sense, and how would I go about constructing this actual formula?

I don't mind using VBA if required, but would prefer to avoid it if possible (company policy, sorry).

答:
@Foxfire And Burns And Burns helped me to solve my problem - I have modified his formulae slightly, to remove the double COUNTIFS, and to account for rows in the master data where both cells are blank - below is what I used.

```<code>=IF (OR($A2<>"",$B2<>""),
        (IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,IF($B2="","",$B2))=0,TRUE,FALSE)
        )
    )
</code>```

This works by returning TRUE or FALSE from the following logical checks - if the final result is TRUE, then the formatting appears.

OR($A2<>"",$B2<>"") - Checks is either of the cells in the master are not blank. - If both cells are blank, this returns FALSE, and does not format anything (see A10:B10).

IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,[see point 3])<1,TRUE,FALSE) - This counts the number of times that both the range $D$2:$D$12 contains the value of cell $A2, AND the range $E$2:$E$12 contains the value of cell $B2. If that number is <1, (zero matches), then the statement returns TRUE and implements the formatting.

IF($B2="","",$B2) - This nested IF statement checks if Cell $B2 is blank, and returns "" if it is blank, or keeps the value of $B2 otherwise. This is because COUNTIFS would see the cell as a 'zero' when blank otherwise (see A9:B9).

I have not used a similar nested if to check if $A2 is blank, because it should not be blank, so it's useful to highlight that the user has made an error in data entry here, too (see A2:B2 - this will remain red once the user inputs a name, as it will no longer match D2:E2.)

Reference image below:

Body:
On Sheet 1, I have a master list of data, with corresponding attributes. Some data has more than one attribute, some has only one, and there is a possibility of blanks. Attributes can be repeated when assigned to a different name.

I've posted some example data below, so we can all talk about the same cells/names etc.

On Sheet 2, there is much more freeform data input/analysis going on. Users are able to select a 'Name' from a dropdown menu using Data Validation, and are then able to select from the available attributes corresponding to that name, again using a dropdown menu. Names and attributes can appear in any order on Sheet 2.

It is important that all pairings are considered in the second worksheet.

Is it possible to use conditional formatting to highlight the 'Name' field (on Sheet 2) until at least one row exists with all possible pairings? In the example below, you can see that we have forgotten to put any info relating to the fact that Sally is Happy, and consequently 'Sally' has been highlighted to draw attention to the fact that there is some missing information.

Current thoughts:
I already have a list of the attributes that match the corresponding name- this is what drives the dropdown menu on Sheet 2, and is generated in a background sheet when a name is picked on Sheet 2. I can count the non-blank cells in this range to find out the total number of pairs that are required.

I would like to then count the number of non-duplicate attributes that are on rows that have the same Name as the current row, and compare this value.

I'm expecting this to get into the realms of array formulae, but may be wrong...
I'm also expecting array formulae to not work directly with conditional formatting, and to require the use of a 'helper column' to drive the formatting. Let me know if this is incorrect?

Something along the lines of the below (formatted as pseudo-code for readability, but this should be read as a high level description, not actual code)

{Count the 1s in the array(AND(
'Check if it's a name match'
If($D$1:$D$10=[$ACurrent],[set flag to 1],[set flag to 0])
'Check if it's a unique value'
[somehow check array values set at 1 to see if there is a duplicate value in column E, and then set the array value to zero if so])
}

Does this approach make sense, and how would I go about constructing this actual formula?

I don't mind using VBA if required, but would prefer to avoid it if possible (company policy, sorry).

Body:
@Foxfire And Burns And Burns helped me to solve my problem - I have modified his formulae slightly, to remove the double COUNTIFS, and to account for rows in the master data where both cells are blank - below is what I used.

=IF (OR($A2<>"",$B2<>""),
        (IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,IF($B2="","",$B2))=0,TRUE,FALSE)
        )
    )

This works by returning TRUE or FALSE from the following logical checks - if the final result is TRUE, then the formatting appears.

OR($A2<>"",$B2<>"") - Checks is either of the cells in the master are not blank. - If both cells are blank, this returns FALSE, and does not format anything (see A10:B10).

IF(COUNTIFS($D$2:$D$12,$A2,$E$2:$E$12,[see point 3])<1,TRUE,FALSE) - This counts the number of times that both the range $D$2:$D$12 contains the value of cell $A2, AND the range $E$2:$E$12 contains the value of cell $B2. If that number is <1, (zero matches), then the statement returns TRUE and implements the formatting.

IF($B2="","",$B2) - This nested IF statement checks if Cell $B2 is blank, and returns "" if it is blank, or keeps the value of $B2 otherwise. This is because COUNTIFS would see the cell as a 'zero' when blank otherwise (see A9:B9).

I have not used a similar nested if to check if $A2 is blank, because it should not be blank, so it's useful to highlight that the user has made an error in data entry here, too (see A2:B2 - this will remain red once the user inputs a name, as it will no longer match D2:E2.)

Reference image below:


问:
how to sum amount for each user?
I have data like this:

```<code> USER_ID   NUM   num_id
1   47641   800    1
2   47641   100    2
3   47641   250    3
4   70919   200    1
5   70919   200    2
6   70919   200    3
7   70919   200    4
</code>```

...

I have no idea what to try, result that i want is this:

```<code> USER_ID   NUM   num_id
1   47641   800    1
2   47641   100    2
3   47641   100    3
4   70919   200    1
5   70919   200    2
6   70919   200    3
7   70919   200    4
...
</code>```

so if for each user, sum of num < 1000 than all num must be same, but if sum of num for each user > 1000 for example for 47641 user we have 800 100 and 250 so we have to sum 800 and 100 and from 250 we need only 100 because 800+100+100=1000 so for num_id=3 we need only 100

I have not written some code...

I only want some ways what to try.
hope you will get idea of problem

答:
```<code>BEGIN TRANSACTION;

/* Create a table called TEST123*/
/* A working example in SQLLITE3*/
 CREATE TABLE TEST123
(USER_ID integer,
NUM integer,
num_id integer);

/* Create few records in this table*/
INSERT INTO TEST123 VALUES(47641,800,1);
INSERT INTO TEST123 VALUES(47641,100,2);
INSERT INTO TEST123 VALUES(47641,250,3);
INSERT INTO TEST123 VALUES(70919,200,1);
INSERT INTO TEST123 VALUES(70919,200,2);
INSERT INTO TEST123 VALUES(70919,200,3);
INSERT INTO TEST123 VALUES(70919,200,4);

/* Display all the records from the table */
SELECT * FROM TEST123;

/*
SELECT a.USER_ID,  a.NUM ,a.num_id , (SELECT SUM(b.NUM) FROM TEST123 AS b where b.num_id<=a.num_id and b.user_id = a.user_id)
FROM TEST123 AS a
GROUP BY a.USER_ID,a.NUM,a.num_id ORDER BY  a.USER_ID,a.num_id;
*/

CREATE TEMPORARY TABLE TEMP_TABLE1 AS
SELECT a.USER_ID AS USER_ID,  a.NUM AS NUM ,a.num_id AS num_id, (SELECT SUM(b.NUM) FROM TEST123 AS b where b.num_id<=a.num_id and b.user_id = a.user_id) AS CUM_NUM
FROM TEST123 AS a
GROUP BY a.USER_ID,a.NUM,a.num_id ORDER BY  a.USER_ID,a.num_id;

SELECT * FROM TEMP_TABLE1;

SELECT USER_ID, NUM, num_id, CASE WHEN CUM_NUM > 1000 THEN (1000 - (CUM_NUM-NUM))  ELSE CUM_NUM END FINAL_CUM_NUM
FROM
TEMP_TABLE1;
</code>```

Title: how to sum amount for each user?

Body:
I have data like this:

 USER_ID   NUM   num_id
1   47641   800    1
2   47641   100    2
3   47641   250    3
4   70919   200    1
5   70919   200    2
6   70919   200    3
7   70919   200    4

...

I have no idea what to try, result that i want is this:

 USER_ID   NUM   num_id
1   47641   800    1
2   47641   100    2
3   47641   100    3
4   70919   200    1
5   70919   200    2
6   70919   200    3
7   70919   200    4
...

so if for each user, sum of num < 1000 than all num must be same, but if sum of num for each user > 1000 for example for 47641 user we have 800 100 and 250 so we have to sum 800 and 100 and from 250 we need only 100 because 800+100+100=1000 so for num_id=3 we need only 100

I have not written some code...

I only want some ways what to try.
hope you will get idea of problem


问:
Is it possible to use ag-grid with vue without a builder?
In particular, can the typescript source of the ag-grid-vue component be compiled then included in a regular html file?</p>

答:
I figured it out:

Download the ag-grid source code, go into the packages/ag-grid-vue directory and do npm install and npm run build. That will put compiled javascript modules in the dist directory that can be used without a build system.

I did have to modify the built javascript slightly to get the AgGridVue object into the global namespace, since I'm not using a module loader.

EDIT:
To get the AgGridVue into the global namespace, add window.AgGridVue = AgGridVue; to the end of the function that returns AgGridVue in ag-grid-vue.umd.js


问:
How to Migrate Posts and Pages from Crafts CMS to Wordpress?
I have a website in Crafts CMS and having 100+ posts and pages. I am creating new wordpress website where I need to copy all the posts and pages from Crafts cms to Wordpress.</p>

答: See https://github.com/craftcms/element-api to create a dump of your content and use a wordpress import process to add the old content.</p>


问:
How to make ScrollView consume touch event even when it's scrolled to the end?
I have an FSPagerView, which has an item that contains scrollable barchart (scrollview having multiple stackviews). When I scroll barchart, if there is a scrollable space, then touch event is consumed by the barchart and it scrolls. If there is no scrollable space on a side and I keep scrolling to that side touching barchart, it does not consume touch event anymore and instead the whole FSPagerView scrolls. How can I make scrollview consume touch event even in such case? In short, I don't want to scroll FSPagerView when touching barchart.

Here is a video:
https://streamable.com/kuxta

答:
You can prioritize the UIGestureRecognizer of the two scroll views using the require(toFail:) method.

Here is the code I tried:

```<code>scrollView.panGestureRecognizer.require(toFail: collectionView.panGestureRecognizer)
</code>```

I don't know if it's exactly what you were looking for. As soon as the collectionView.panGestureRecognizer detects something, the scroll view won't scroll.

Body:
You can prioritize the UIGestureRecognizer of the two scroll views using the require(toFail:) method.

Here is the code I tried:

scrollView.panGestureRecognizer.require(toFail: collectionView.panGestureRecognizer)

I don't know if it's exactly what you were looking for. As soon as the collectionView.panGestureRecognizer detects something, the scroll view won't scroll.